void BcMat4d::scale( const BcVec4d& Scale ) { row0( BcVec4d( Scale.x(), 0.0f, 0.0f, 0.0f ) ); row1( BcVec4d( 0.0f, Scale.y(), 0.0f, 0.0f ) ); row2( BcVec4d( 0.0f, 0.0f, Scale.z(), 0.0f ) ); row3( BcVec4d( 0.0f, 0.0f, 0.0f, Scale.w() ) ); }
void CoronaRenderer::setAnimatedTransformationMatrix(Corona::AnimatedAffineTm& atm, mtco_MayaObject *obj) { MMatrix to, from; // a segment contains start and end, 2 mb steps are one segment, 3 mb steps are 2 segments int numSegments = (obj->transformMatrices.size() - 1) * ((int)this->mtco_renderGlobals->doMb) ; atm.setSegments(numSegments); for( size_t mId = 0; mId < (numSegments + 1); mId++) { MMatrix c = this->mtco_renderGlobals->globalConversionMatrix; //logger.debug(MString("globalConv:")); //logger.debug(MString("") + c[0][0] + " " + c[0][1] + " " + c[0][2] + " " + c[0][3]); //logger.debug(MString("") + c[1][0] + " " + c[1][1] + " " + c[1][2] + " " + c[1][3]); //logger.debug(MString("") + c[2][0] + " " + c[2][1] + " " + c[2][2] + " " + c[2][3]); //logger.debug(MString("") + c[3][0] + " " + c[3][1] + " " + c[3][2] + " " + c[3][3]); MMatrix t = (obj->transformMatrices[mId] * c).transpose(); Corona::AffineTm tm; Corona::Float4 row1(t[0][0],t[0][1],t[0][2],t[0][3]); Corona::Float4 row2(t[1][0],t[1][1],t[1][2],t[1][3]); Corona::Float4 row3(t[2][0],t[2][1],t[2][2],t[2][3]); tm = Corona::AffineTm(row1, row2, row3); atm[mId] = Corona::AffineTm::IDENTITY; atm[mId] = tm; } }
Matrix4 Matrix4::multiply(Matrix4 a) { Matrix4 b; /* for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { b.m[i][j] = m[0][j] * a.m[i][0] + m[1][j] * a.m[i][1] + m[2][j] * a.m[i][2] + m[3][j] * a.m[i][3]; } }*/ Vector4 row1(m[0][0], m[1][0], m[2][0], m[3][0]); Vector4 row2(m[0][1], m[1][1], m[2][1], m[3][1]); Vector4 row3(m[0][2], m[1][2], m[2][2], m[3][2]); Vector4 row4(m[0][3], m[1][3], m[2][3], m[3][3]); Vector4 col1(a.m[0][0], a.m[0][1], a.m[0][2], a.m[0][3]); Vector4 col2(a.m[1][0], a.m[1][1], a.m[1][2], a.m[1][3]); Vector4 col3(a.m[2][0], a.m[2][1], a.m[2][2], a.m[2][3]); Vector4 col4(a.m[3][0], a.m[3][1], a.m[3][2], a.m[3][3]); b.set(row1.dot(col1), row2.dot(col1), row3.dot(col1), row4.dot(col1), row1.dot(col2), row2.dot(col2), row3.dot(col2), row4.dot(col2), row1.dot(col3), row2.dot(col3), row3.dot(col3), row4.dot(col3), row1.dot(col4), row2.dot(col4), row3.dot(col4), row4.dot(col4)); return b; }
AglQuaternion AglMatrix::GetRotation() const { AglVector3 row0(data[0], data[1], data[2]); AglVector3 row1(data[4], data[5], data[6]); AglVector3 row2(data[8], data[9], data[10]); float lrow0 = AglVector3::length(row0); float lrow1 = AglVector3::length(row1); float lrow2 = AglVector3::length(row2); row0 *= (1/lrow0); row1 *= (1/lrow1); row2 *= (1/lrow2); //Find the largest factor. float qx, qy, qz, qw; if (row0[0] + row1[1] + row2[2] > 0.0f) //Use w { float t = row0[0] + row1[1] + row2[2] + data[15]; float s = 0.5f / sqrt(t); qw = s * t; qz = (row0[1] - row1[0]) * s; qy = (row2[0] - row0[2]) * s; qx = (row1[2] - row2[1]) * s; } else if (row0[0] > row1[1] && row0[0] > row2[2]) //Use x { float t = row0[0] - row1[1] - row2[2] + data[15]; float s = 0.5f / sqrt(t); qx = s * t; qy = (row0[1] + row1[0]) * s; qz = (row2[0] + row0[2]) * s; qw = (row1[2] - row2[1]) * s; } else if (row1[1] > row2[2]) //Use y { float t = -row0[0] + row1[1] - row2[2] + data[15]; float s = 0.5f / sqrt(t); qy = s * t; qx = (row0[1] + row1[0]) * s; qw = (row2[0] - row0[2]) * s; qz = (row1[2] + row2[1]) * s; } else //Use z { float t = -row0[0] - row1[1] + row2[2] + data[15]; float s = 0.5f / sqrt(t); qz = s * t; qw = (row0[1] - row1[0]) * s; qx = (row2[0] + row0[2]) * s; qy = (row1[2] + row2[1]) * s; } return AglQuaternion(qx, qy, qz, qw); }
// Print a matrix33 to a file void matrix33::fprint(FILE* file, char * str) const { fprintf(file, "%smatrix33:\n", str); vector3 row0(col[0][0], col[1][0], col[2][0]); row0.fprint(file, "\t"); vector3 row1(col[0][1], col[1][1], col[2][1]); row1.fprint(file, "\t"); vector3 row2(col[0][2], col[1][2], col[2][2]); row2.fprint(file, "\t"); }
void model1_state::view_t::transform_vector(glm::vec3& p) const { glm::vec3 q(p); glm::vec3 row1(translation[0], translation[3], translation[6]); glm::vec3 row2(translation[1], translation[4], translation[7]); glm::vec3 row3(translation[2], translation[5], translation[8]); p = glm::vec3(glm::dot(q, row1), glm::dot(q, row2), glm::dot(q, row3)); //p->set_x(translation[0] * q.x() + translation[3] * q.y() + translation[6] * q.z()); //p->set_y(translation[1] * q.x() + translation[4] * q.y() + translation[7] * q.z()); //p->set_z(translation[2] * q.x() + translation[5] * q.y() + translation[8] * q.z()); }
// Return a matrix to represent a nonuniform scale with the given factors. Matrix4x4 scaling(const Vector3D& scale) { Vector4D row1(scale[0], 0, 0, 0); Vector4D row2(0, scale[1], 0, 0); Vector4D row3(0, 0, scale[2], 0); Vector4D row4(0, 0, 0, 1); Matrix4x4 s(row1, row2, row3, row4); return s; }
bool ROSToKlampt(const tf::Transform& T,RigidTransform& kT) { kT.t.set(T.getOrigin().x(),T.getOrigin().y(),T.getOrigin().z()); Vector3 row1(T.getBasis()[0].x(),T.getBasis()[0].y(),T.getBasis()[0].z()); Vector3 row2(T.getBasis()[1].x(),T.getBasis()[1].y(),T.getBasis()[1].z()); Vector3 row3(T.getBasis()[2].x(),T.getBasis()[2].y(),T.getBasis()[2].z()); kT.R.setRow1(row1); kT.R.setRow2(row2); kT.R.setRow3(row3); return true; }
AglVector3 AglMatrix::GetScale() const { AglVector3 row0(data[0], data[1], data[2]); AglVector3 row1(data[4], data[5], data[6]); AglVector3 row2(data[8], data[9], data[10]); float lrow0 = AglVector3::length(row0); float lrow1 = AglVector3::length(row1); float lrow2 = AglVector3::length(row2); return AglVector3(lrow0, lrow1, lrow2); }
std::vector<QVector> ViewingParams::updateVewingTranformationMatrix(){ QVector row1(eyeCoord[0].getX(),eyeCoord[1].getX(),eyeCoord[2].getX(),eye.getX()); QVector row2(eyeCoord[0].getY(),eyeCoord[1].getY(),eyeCoord[2].getY(),eye.getY()); QVector row3(eyeCoord[0].getZ(),eyeCoord[1].getZ(),eyeCoord[2].getZ(),eye.getZ()); QVector row4(0,0,0,1); transMatrix.clear(); transMatrix.push_back(row1); transMatrix.push_back(row2); transMatrix.push_back(row3); transMatrix.push_back(row4); return transMatrix; }
// Return a matrix to represent a displacement of the given vector. Matrix4x4 translation(const Vector3D& displacement) { Vector4D row1(1, 0, 0, displacement[0]); Vector4D row2(0, 1, 0, displacement[1]); Vector4D row3(0, 0, 1, displacement[2]); Vector4D row4(0, 0, 0, 1); Matrix4x4 t(row1, row2, row3, row4); return t; }
int main() { tableau t1; std::vector<unsigned int> row1(10); std::vector<unsigned int> row2(8); t1.push_back(row1); t1.push_back(row2); tableau::iterator it = t1.begin(); for ( ; it != t1.end(); ++it) { //display rows of tableau } return 0; }
// --[ Method ]--------------------------------------------------------------- // // - Class : CMatrix // // - prototype : CMatrix Inverse() // // - Purpose : Returns the inverse transformation matrix. // // - Note : IMPORTANT: Algorithm only valid for orthogonal matrices! // // ----------------------------------------------------------------------------- CMatrix CMatrix::Inverse() const { CMatrix result; // Transpose rotation submatrix CVector3 row0(m_fM[0][0], m_fM[1][0], m_fM[2][0]); CVector3 row1(m_fM[0][1], m_fM[1][1], m_fM[2][1]); CVector3 row2(m_fM[0][2], m_fM[1][2], m_fM[2][2]); CVector3 position(m_fM[0][3], m_fM[1][3], m_fM[2][3]); CVector3 invPosition; // Solve ecuation system invPosition.SetX((-row0) * position); invPosition.SetY((-row1) * position); invPosition.SetZ((-row2) * position); // Get scale values CVector3 scale = Scale(); float sqrSclX = scale.X(); sqrSclX *= sqrSclX; float sqrSclY = scale.Y(); sqrSclY *= sqrSclY; float sqrSclZ = scale.Z(); sqrSclZ *= sqrSclZ; // Shouldn't happen: assert(!IS_ZERO(sqrSclX)); assert(!IS_ZERO(sqrSclY)); assert(!IS_ZERO(sqrSclZ)); // Normalize axis and multiply by the inverse scale. row0 = row0 / sqrSclX; row1 = row1 / sqrSclY; row2 = row2 / sqrSclZ; // Insert values result.SetRow0(row0.X(), row0.Y(), row0.Z(), invPosition.X()); result.SetRow1(row1.X(), row1.Y(), row1.Z(), invPosition.Y()); result.SetRow2(row2.X(), row2.Y(), row2.Z(), invPosition.Z()); result.SetRow3( 0.0f, 0.0f, 0.0f, 1.0f); return result; }
FMatrix OSVRHMDDescription::GetProjectionMatrix(float left, float right, float bottom, float top, float nearClip, float farClip) const { // original code //float sumRightLeft = static_cast<float>(right + left); //float sumTopBottom = static_cast<float>(top + bottom); //float inverseRightLeft = 1.0f / static_cast<float>(right - left); //float inverseTopBottom = 1.0f / static_cast<float>(top - bottom); //FPlane row1(2.0f * inverseRightLeft, 0.0f, 0.0f, 0.0f); //FPlane row2(0.0f, 2.0f * inverseTopBottom, 0.0f, 0.0f); //FPlane row3((sumRightLeft * inverseRightLeft), (sumTopBottom * inverseTopBottom), 0.0f, 1.0f); //FPlane row4(0.0f, 0.0f, zNear, 0.0f); // OSVR Render Manager OSVR_Projection_to_D3D with adjustment for unreal (from steamVR plugin) OSVR_ProjectionMatrix projection; projection.left = static_cast<double>(left); projection.right = static_cast<double>(right); projection.top = static_cast<double>(top); projection.bottom = static_cast<double>(bottom); projection.nearClip = static_cast<double>(nearClip); // @todo Since farClip may be FLT_MAX, round-trip casting to double // and back (via the OSVR_Projection_to_Unreal call) it should // be checked for conversion issues. projection.farClip = static_cast<double>(farClip); float p[16]; OSVR_Projection_to_Unreal(p, projection); FPlane row1(p[0], p[1], p[2], p[3]); FPlane row2(p[4], p[5], p[6], p[7]); FPlane row3(p[8], p[9], p[10], p[11]); FPlane row4(p[12], p[13], p[14], p[15]); FMatrix ret = FMatrix(row1, row2, row3, row4); //ret.M[3][3] = 0.0f; //ret.M[2][3] = 1.0f; //ret.M[2][2] = 0.0f; //ret.M[3][2] = nearClip; // This was suggested by Nick at Epic, but doesn't seem to work? Black screen. //ret.M[2][2] = nearClip / (nearClip - farClip); //ret.M[3][2] = -nearClip * nearClip / (nearClip - farClip); // Adjustment suggested on a forum post for an off-axis projection. Doesn't work. //ret *= 1.0f / ret.M[0][0]; //ret.M[3][2] = GNearClippingPlane; return ret; }
TEST(ArgParserTests, getArgv_stringArray_return2DArray) { std::vector<String> argArray; argArray.push_back("stub1"); argArray.push_back("stub2"); argArray.push_back("stub3 space"); const char** argv = ArgParser::getArgv(argArray); String row1(argv[0]); String row2(argv[1]); String row3(argv[2]); EXPECT_EQ("stub1", row1); EXPECT_EQ("stub2", row2); EXPECT_EQ("stub3 space", row3); delete[] argv; }
Json::Value SkJSONCanvas::MakeMatrix(const SkMatrix& matrix) { Json::Value result(Json::arrayValue); Json::Value row1(Json::arrayValue); row1.append(Json::Value(matrix[0])); row1.append(Json::Value(matrix[1])); row1.append(Json::Value(matrix[2])); result.append(row1); Json::Value row2(Json::arrayValue); row2.append(Json::Value(matrix[3])); row2.append(Json::Value(matrix[4])); row2.append(Json::Value(matrix[5])); result.append(row2); Json::Value row3(Json::arrayValue); row3.append(Json::Value(matrix[6])); row3.append(Json::Value(matrix[7])); row3.append(Json::Value(matrix[8])); result.append(row3); return result; }
int CalcSphereCenter (const Point<3> ** pts, Point<3> & c) { Vec3d row1 (*pts[0], *pts[1]); Vec3d row2 (*pts[0], *pts[2]); Vec3d row3 (*pts[0], *pts[3]); Vec3d rhs(0.5 * (row1*row1), 0.5 * (row2*row2), 0.5 * (row3*row3)); Transpose (row1, row2, row3); Vec3d sol; if (SolveLinearSystem (row1, row2, row3, rhs, sol)) { (*testout) << "CalcSphereCenter: degenerated" << endl; return 1; } c = *pts[0] + sol; return 0; }
vector<vector<int>> generate(int numRows) { vector<vector<int>> res; if(numRows == 0) return res; vector<int> row1(1,1); res.push_back(row1); if(numRows == 1){ return res; } vector<int> row2(2,1); res.push_back(row2); if(numRows == 2){ return res; } for(int i = 3; i <= numRows; i++){ vector<int> row(i, 1); for(int j = 1; j < i - 1; j++){ row[j] = res[i-2][j-1] + res[i-2][j]; } res.push_back(row); } return res; }
void StressDivergenceTruss::computeStiffness(ColumnMajorMatrix & stiff_global) { RealGradient orientation( (*_orientation)[0] ); orientation /= orientation.size(); // Now get a rotation matrix // The orientation is the first row of the matrix. // Need two other directions. VectorValue<Real> & row1( orientation ); VectorValue<Real> row3( row1 ); unsigned zero_index(0); if (row3(1) != 0) { zero_index = 1; } if (row3(2) != 0) { zero_index = 2; } row3(zero_index) += 1; VectorValue<Real> row2 = orientation.cross( row3 ); row3 = orientation.cross( row2 ); Real k = _E_over_L[0] * _area[0]; stiff_global(0,0) = row1(0)*row1(0)*k; stiff_global(0,1) = row1(0)*row2(0)*k; stiff_global(0,2) = row1(0)*row3(0)*k; stiff_global(1,0) = row2(0)*row1(0)*k; stiff_global(1,1) = row2(0)*row2(0)*k; stiff_global(1,2) = row2(0)*row3(0)*k; stiff_global(2,0) = row3(0)*row1(0)*k; stiff_global(2,1) = row3(0)*row2(0)*k; stiff_global(2,2) = row3(0)*row3(0)*k; }
void plot_pad_size_in_layer(TString digiPar="trd.v13/trd_v13g.digi.par", Int_t nlines=1, Int_t nrows_in_sec=0, Int_t alllayers=1) { gStyle->SetPalette(1,0); gROOT->SetStyle("Plain"); gStyle->SetPadTickX(1); gStyle->SetPadTickY(1); gStyle->SetOptStat(kFALSE); gStyle->SetOptTitle(kFALSE); Bool_t read = false; TH2I *fLayerDummy = new TH2I("LayerDummy","",1200,-600,600,1000,-500,500); fLayerDummy->SetXTitle("x-coordinate [cm]"); fLayerDummy->SetYTitle("y-coordinate [cm]"); fLayerDummy->GetXaxis()->SetLabelSize(0.02); fLayerDummy->GetYaxis()->SetLabelSize(0.02); fLayerDummy->GetZaxis()->SetLabelSize(0.02); fLayerDummy->GetXaxis()->SetTitleSize(0.02); fLayerDummy->GetXaxis()->SetTitleOffset(1.5); fLayerDummy->GetYaxis()->SetTitleSize(0.02); fLayerDummy->GetYaxis()->SetTitleOffset(2); fLayerDummy->GetZaxis()->SetTitleSize(0.02); fLayerDummy->GetZaxis()->SetTitleOffset(-2); TString title; TString title1, title2, title3; TString buffer; TString firstModule = ""; Int_t blockCounter(0), startCounter(0); // , stopCounter(0); Double_t msX(0), msY(0), mpX(0), mpY(0), mpZ(0), psX(0), psY(0); Double_t ps1X(0), ps1Y(0), ps2X(0), ps2Y(0), ps3X(0), ps3Y(0); Int_t modId(0), layerId(0); Double_t sec1(0), sec2(0), sec3(0); Double_t row1(0), row2(0), row3(0); std::map<float, TCanvas*> layerView;// map key is z-position of modules std::map<float, TCanvas*>::iterator it; ifstream digipar; digipar.open(digiPar.Data(), ifstream::in); while (digipar.good()) { digipar >> buffer; //cout << "(" << blockCounter << ") " << buffer << endl; if (blockCounter == 19) firstModule = buffer; if (buffer == (firstModule + ":")){ //cout << buffer << " <===========================================" << endl; read = true; } if (read) { startCounter++; if (startCounter == 1) // position of module position in x { modId = buffer.Atoi(); layerId = (modId & (15 << 4)) >> 4; // from CbmTrdAddress.h } if (startCounter == 5) // position of module position in x mpX = buffer.Atof(); if (startCounter == 6) // position of module position in y mpY = buffer.Atof(); if (startCounter == 7) // position of module position in z mpZ = buffer.Atof(); if (startCounter == 8) // position of module size in x msX = buffer.Atof(); if (startCounter == 9) // position of module size in y msY = buffer.Atof(); if (startCounter == 12) // sector 1 size in y sec1 = buffer.Atof(); if (startCounter == 13) // position of pad size in x - do not take the backslash (@14) ps1X = buffer.Atof(); if (startCounter == 15) // position of pad size in y ps1Y = buffer.Atof(); if (startCounter == 17) // sector 2 size in y sec2 = buffer.Atof(); if (startCounter == 18) // position of pad size in x { ps2X = buffer.Atof(); psX = ps2X; // for backwards compatibility - sector 2 is default sector } if (startCounter == 19) // position of pad size in y { ps2Y = buffer.Atof(); psY = ps2Y; // for backwards compatibility - sector 2 is default sector } if (startCounter == 21) // sector 3 size in y sec3 = buffer.Atof(); if (startCounter == 22) // position of pad size in x ps3X = buffer.Atof(); if (startCounter == 23) // position of pad size in y ps3Y = buffer.Atof(); // if (startCounter == 23) // last element // { // printf("moduleId : %d, %d\n", modId, layerId); // printf("pad size sector 1: (%.2f cm, %.2f cm) pad area: %.2f cm2\n", ps1X, ps1Y, ps1X*ps1Y); // printf("pad size sector 2: (%.2f cm, %.2f cm) pad area: %.2f cm2\n", ps2X, ps2Y, ps2X*ps2Y); // printf("pad size sector 3: (%.2f cm, %.2f cm) pad area: %.2f cm2\n", ps3X, ps3Y, ps3X*ps3Y); // printf("rows per sector : %.1f %.1f %.1f\n", sec1/ps1Y, sec2/ps2Y, sec3/ps3Y); // printf("\n"); // } //printf("module position: (%.1f, %.1f, %.1f) module size: (%.1f, %.1f) pad size: (%.2f, %.2f) pad area: %.2f\n",mpX,mpY,mpZ,2*msX,2*msY,psX,psY,psX*psY); if (startCounter == 23) { // if last element is reached startCounter = 0; // reset if ( alllayers == 0 ) if ( !((layerId == 0) || (layerId == 4) || (layerId == 8)) ) // plot only 1 layer per station continue; row1 = sec1 / ps1Y; row2 = sec2 / ps2Y; row3 = sec3 / ps3Y; it = layerView.find(mpZ); if (it == layerView.end()){ // title.Form("pad_size_layer_at_z_%.2fm",mpZ); title.Form("%02d_pad_size_layer%02d", layerId, layerId); layerView[mpZ] = new TCanvas(title,title,1200,1000); fLayerDummy->DrawCopy(""); // now print cm2 in the center layerView[mpZ]->cd(); title.Form("cm^{2}"); // print cm2 TPaveText *text = new TPaveText(0 - 28.5, 0 - 28.5, 0 + 28.5, 0 + 28.5 ); text->SetFillStyle(1001); text->SetLineColor(1); text->SetFillColor(kWhite); text->AddText(title); text->Draw("same"); } // print pad size in each module layerView[mpZ]->cd(); // title.Form("%2.0fcm^{2}",psX*psY); // print pad size // title.Form("%.0f",psX*psY); // print pad size - 1 digit TPaveText *text = new TPaveText(mpX - msX, mpY - msY, mpX + msX, mpY + msY ); text->SetFillStyle(1001); text->SetLineColor(1); // text->SetFillColor(kViolet); // vary background color // if ((int)(psX*psY+.5) == 2) // { // text->SetFillColor(kOrange + 9); // } // else if (psX*psY <= 1.1) { text->SetFillColor(kOrange + 10); } else if (psX*psY <= 2.1) { text->SetFillColor(kOrange - 3); } else if (psX*psY <= 3.1) { text->SetFillColor(kOrange - 4); } else if (psX*psY <= 5) { text->SetFillColor(kOrange + 10 - ((int)(psX*psY+.5)-1) * 2); // printf("%2.1f: %d\n", psX*psY, 10 - ((int)(psX*psY+.5)-1) * 2); } else if (psX*psY <= 10) { text->SetFillColor(kSpring + 10 - ((int)(psX*psY+.5)-4) * 2); // printf("%2.1f: %d\n", psX*psY, 10 - ((int)(psX*psY+.5)-4) * 2); } else if (psX*psY > 10) { text->SetFillColor(kGreen); // printf("%2.1f: %s\n", psX*psY, "green"); } if (nrows_in_sec == 1) // print number of rows in sector { title1.Form("%3.1f - %2.0f", ps1X*ps1Y, row1); // print pad size and nrows - 2 digits - sector 1 title2.Form("%3.1f - %2.0f", ps2X*ps2Y, row2); // print pad size and nrows - 2 digits - sector 2 title3.Form("%3.1f - %2.0f", ps3X*ps3Y, row3); // print pad size and nrows - 2 digits - sector 3 } else { title1.Form("%3.1f",ps1X*ps1Y); // print pad size - 2 digits - sector 1 title2.Form("%3.1f",ps2X*ps2Y); // print pad size - 2 digits - sector 2 title3.Form("%3.1f",ps3X*ps3Y); // print pad size - 2 digits - sector 3 } if (nlines==1) // plot pad size for central sector only { text->AddText(title2); } else // plot pad size for all 3 sectors { text->AddText(title1); text->AddText(title2); text->AddText(title3); } text->Draw("same"); //layerView[mpZ]->Update(); } } blockCounter++; }
LPSolver::Status_Sol LSmear::getdual(IntervalMatrix& J, const IntervalVector& box, Vector& dual) const { int _goal_var = goal_var(); bool minimize=true; if (_goal_var == -1){ _goal_var = RNG::rand()%box.size(); minimize=RNG::rand()%2; } // The linear system is created mylinearsolver->clean_ctrs(); mylinearsolver->set_bounds(box); mylinearsolver->set_bounds_var(_goal_var, Interval(-1e10,1e10)); int nb_lctrs[sys.f_ctrs.image_dim()]; /* number of linear constraints generated by nonlinear constraint*/ for (int i=0; i<sys.f_ctrs.image_dim(); i++) { Vector row1(sys.nb_var); Interval ev(0.0); for (int j=0; j<sys.nb_var; j++) { row1[j] = J[i][j].mid(); ev -= Interval(row1[j])*box[j].mid(); } ev+= sys.f_ctrs.eval(i,box.mid()).mid(); nb_lctrs[i]=1; if (i!=goal_ctr()) { if (sys.ops[i] == LEQ || sys.ops[i] == LT){ mylinearsolver->add_constraint( row1, sys.ops[i], (-ev).ub()); } else if (sys.ops[i] == GEQ || sys.ops[i] == GT) mylinearsolver->add_constraint( row1, sys.ops[i], (-ev).lb()); else { //op=EQ mylinearsolver->add_constraint( row1, LT, (-ev).ub()); mylinearsolver->add_constraint( row1, GT, (-ev).lb()); nb_lctrs[i]=2; } } else if (goal_to_consider(J,i)) mylinearsolver->add_constraint( row1, LEQ, (-ev).ub()); else // the goal is equal to a variable : the goal constraint is useless. nb_lctrs[i]=0; } //the linear system is solved LPSolver::Status_Sol stat=LPSolver::UNKNOWN; try { mylinearsolver->set_obj_var(_goal_var, (minimize)? 1.0:-1.0); stat = mylinearsolver->solve(); if (stat == LPSolver::OPTIMAL) { // the dual solution : used to compute the bound dual.resize(mylinearsolver->get_nb_rows()); dual = mylinearsolver->get_dual_sol(); int k=0; //number of multipliers != 0 int ii=0; for (int i=0; i<sys.f_ctrs.image_dim(); i++) { if (nb_lctrs[i]==2) { dual[sys.nb_var+i]=dual[sys.nb_var+ii]+dual[sys.nb_var+ii+1]; ii+=2; } else { dual[sys.nb_var+i]=dual[sys.nb_var+ii]; ii++; } if (std::abs(dual[sys.nb_var+i])>1e-10) k++; } if(k<2) { stat = LPSolver::UNKNOWN; } } } catch (LPException&) { stat = LPSolver::UNKNOWN; } return stat; }
int LinearRelaxXTaylor::X_Linearization(const IntervalVector& savebox, int ctr, corner_point cpoint, CmpOp op, IntervalVector& G2, int id_point, int& nb_nonlinear_vars, LinearSolver& lp_solver) { IntervalVector G = G2; int n = sys.nb_var; int nonlinear_var = 0; if (id_point != 0 && linear_ctr[ctr]) return 0; // only one corner for a linear constraint /* bool* corner=NULL; if(!linear[ctr]){ // best not implemented in version 2.0 BNE if(cpoint==BEST){ corner= new bool[n]; best_corner(ctr, op, G, corner); } } */ IntervalVector box(savebox); Interval ev(0.0); Interval tot_ev(0.0); Vector row1(n); for (int j=0; j< n; j++) { //cout << "[LinearRelaxXTaylor] variable n°" << j << endl; if (sys.ctrs[ctr].f.used(j)) { if (lmode == HANSEN && !linear[ctr][j]) // get the partial derivative of ctr w.r.t. var n°j G[j]=df[ctr*n+j].eval(box); } else continue; //cout << "[LinearRelaxXTaylor] coeffs=" << G[j] << endl; if (G[j].diam() > max_diam_deriv) { // box = savebox; // [gch] where box has been modified? at the end of the loop (for Hansen computation) [bne] return 0; // To avoid problems with SoPleX } if (linear[ctr][j]) cpoint = INF_X; else if (G[j].diam() > 1e-10) nonlinear_var++; bool inf_x; /* for GREEDY heuristics :not implemented in v2 IntervalVector save; double fh_inf, fh_sup; double D; */ switch (cpoint) { /* case BEST: inf_x=corner[j]; last_rnd[j]=inf_x? 0:1; break; */ case INF_X: inf_x = true; break; case SUP_X: inf_x = false; break; case RANDOM: last_rnd[j] = rand(); inf_x = (last_rnd[j] % 2 == 0); break; case K4: if (id_point == 0) { inf_x = (rand() % 2 == 0); base_coin[j] = inf_x; } else if (nb_nonlinear_vars < 3) { if (id_point == 1) inf_x = !base_coin[j]; else return 0; } else if (G[j].diam() <= 1e-10) { inf_x = (rand() % 2 == 0); } else if (id_point == 1) { if (((double) nonlinear_var) <= (((double) nb_nonlinear_vars)/ 3.0)) inf_x = base_coin[j]; else inf_x = !base_coin[j]; } else if (id_point == 2) { if (((double) nonlinear_var )> ((double) nb_nonlinear_vars)/ 3.0 && (double) nonlinear_var <= 2 * (double) nb_nonlinear_vars / 3.0) inf_x = base_coin[j]; else inf_x = !base_coin[j]; } else if (id_point == 3) { if (((double) nonlinear_var) > 2 * ((double) nb_nonlinear_vars) / 3.0) inf_x = base_coin[j]; else inf_x = !base_coin[j]; } break; case RANDOM_INV: inf_x = (last_rnd[j] % 2 != 0); break; case NEG: inf_x = (last_rnd[j] % 2 != 0); break; /* not implemented in v2.0 case GREEDY1: inf_x=((abs(Inf(G(j+1))) < abs(Sup(G(j+1))) && (op == LEQ || op== LT)) || (abs(Inf(G(j+1))) >= abs(Sup(G(j+1))) && (op == GEQ || op== GT)) )? true:false; break; case MONO: if (ctr==goal_ctr && ((Inf(G(j+1)) >0 && (op == LEQ || op== LT)) || (Sup (G(j+1)) < 0 && (op == GEQ || op== GT)))) inf_x = true; else if (ctr == goal_ctr && ((Sup(G(j+1)) <0 && (op == LEQ || op== LT)) || (Inf(G(j+1)) > 0 && (op == GEQ || op== GT)))) inf_x=false; else inf_x = (rand()%2==0); last_rnd[j]=inf_x? 0:1; break; case NEGMONO: if ((Inf(G(j+1)) >0 && (op == LEQ || op== LT)) || (Sup (G(j+1)) < 0 && (op == GEQ || op== GT))) inf_x = false; else if ((Sup(G(j+1)) <0 && (op == LEQ || op== LT)) || (Inf(G(j+1)) > 0 && (op == GEQ || op== GT))) inf_x=true; else inf_x = (rand()%2==0); last_rnd[j]=inf_x? 0:1; break; */ /* case GREEDY7: //select the coin nearest to the loup if(goal_ctr!=-1 && Dimension(Optimizer::global_optimizer())>0){ // if(j==0)cout<< Optimizer::global_optimizer()<<end; inf_x=(abs(Optimizer::global_optimizer()(j+1)-Inf(savebox(j+1))) < abs(Optimizer::global_optimizer()(j+1)-Sup(savebox(j+1))))? true:false; }else{ inf_x=(rand()%2==0); } break; */ /* case GREEDY6: save=space.box; fh_inf, fh_sup; D=Diam(savebox(j+1)); space.box=Mid(space.box); space.box(j+1)=Inf(savebox(j+1)); fh_inf=Mid(sys.ctr(ctr).eval(space)); space.box(j+1)=Sup(savebox(j+1)); fh_sup=Mid(sys.ctr(ctr).eval(space)); if (op == LEQ || op== LT) inf_x=((fh_sup-fh_inf)/(REAL)(n-1) - 0.5*D*(Inf(G(j+1))+Sup(G(j+1))) > 0)? false:true; else inf_x=((fh_sup-fh_inf)/(REAL)(n-1) - 0.5*D*(Inf(G(j+1))+Sup(G(j+1))) < 0)? false:true; last_rnd[j]=inf_x? 0:1; space.box=save; break; case GREEDY5: save=space.box; fh_inf, fh_sup; D=Diam(savebox(j+1)); space.box=Mid(space.box); space.box(j+1)=Inf(savebox(j+1)); fh_inf=Mid(sys.ctr(ctr).eval(space)); space.box(j+1)=Sup(savebox(j+1)); fh_sup=Mid(sys.ctr(ctr).eval(space)); if (op == LEQ || op== LT) inf_x=(fh_sup-fh_inf - 0.5*D*(Inf(G(j+1))+Sup(G(j+1))) > 0)? false:true; else inf_x=(fh_sup-fh_inf - 0.5*D*(Inf(G(j+1))+Sup(G(j+1))) < 0)? false:true; last_rnd[j]=inf_x? 0:1; space.box=save; break; */ default: last_rnd[j] = rand(); inf_x = (last_rnd[j] % 2 == 0); break; } // cout << " j " << j << " " << savebox[j] << G[j] << endl; box[j]=inf_x? savebox[j].lb():savebox[j].ub(); Interval a = ((inf_x && (op == LEQ || op== LT)) || (!inf_x && (op == GEQ || op== GT))) ? G[j].lb() : G[j].ub(); row1[j] = a.mid(); ev -= a*box[j]; } // cout << " ev " << ev << endl; /* used in BEST not implemented in v2.0 if(corner) delete[] corner; */ ev+= sys.ctrs[ctr].f.eval(box); if(id_point==0) nb_nonlinear_vars=nonlinear_var; for(int j=0;j<n;j++) tot_ev+=row1[j]*savebox[j]; //natural evaluation of the left side of the linear constraint bool added=false; if (op == LEQ || op == LT) { //g(xb) + a1' x1 + ... + an xn <= 0 if(tot_ev.lb()>(-ev).ub()) throw EmptyBoxException(); // the constraint is not satisfied if((-ev).ub()<tot_ev.ub()) { // otherwise the constraint is satisfied for any point in the box lp_solver.addConstraint( row1, LEQ, (-ev).ub()); added=true; } } else { if(tot_ev.ub()<(-ev).lb()) throw EmptyBoxException(); if ((-ev).lb()>tot_ev.lb()) { lp_solver.addConstraint( row1, GEQ, (-ev).lb() ); added=true; } } //box=savebox; return (added)? 1:0; }
//---------------------------------------------------------------------- void CondProbTableTest::RunTests() { // Our 4 rows vector<vector<Real> > rows; rows.resize(numRows()); rows[0] = makeRow((Real)0.0, (Real)0.4, (Real)0.0); rows[1] = makeRow((Real)1.0, (Real)0.0, (Real)0.0); rows[2] = makeRow((Real)0.0, (Real)0.0, (Real)0.6); rows[3] = makeRow((Real)0.0, (Real)0.6, (Real)0.4); // Test constructing without # of columns { CondProbTable table; // Add the 4 rows for (Size i=0; i<numRows(); i++) table.updateRow((UInt)i, rows[i]); // Test it testTable ("Dynamic columns:", table, rows); } // Test constructing and growing the columns dynamically { CondProbTable table; // Add the 2nd row first which has just 1 column vector<Real> row1(1); row1[0] = rows[1][0]; table.updateRow(1, row1); // Add the first row first with just 2 columns vector<Real> row0(2); row0[0] = rows[0][0]; row0[1] = rows[0][1]; table.updateRow(0, row0); for (Size i=2; i<numRows(); i++) table.updateRow((UInt)i, rows[i]); // Test it testTable ("Growing columns:", table, rows); } // Make a table with 3 columns { CondProbTable table((UInt)numCols()); // Add the 4 rows for (Size i=0; i<numRows(); i++) table.updateRow((UInt)i, rows[i]); // Test it testTable ("Fixed columns:", table, rows); } // Make a table, save to stream, then reload and test { CondProbTable table((UInt)numCols()); // Add the 4 rows for (Size i=0; i<numRows(); i++) table.updateRow((UInt)i, rows[i]); // Save it stringstream state; table.saveState (state); CondProbTable newTable; newTable.readState (state); testTable ("Restored from state:", newTable, rows); } // Test saving an empty table { CondProbTable table; // Save it stringstream state; table.saveState (state); // Read it in CondProbTable newTable; newTable.readState (state); // Add the 4 rows for (Size i=0; i<numRows(); i++) newTable.updateRow((UInt)i, rows[i]); // Test it testTable ("Restored from empty state:", newTable, rows); } }
void AglMatrix::matrixToComponents(AglMatrix pMatrix, AglVector3& pScale, AglQuaternion& pQuaternion, AglVector3& pTranslation) { // http://software.intel.com/sites/default/files/m/d/4/1/d/8/293748.pdf // Real-Time Rendering //Scale AglVector3 row0(pMatrix[0], pMatrix[1], pMatrix[2]); AglVector3 row1(pMatrix[4], pMatrix[5], pMatrix[6]); AglVector3 row2(pMatrix[8], pMatrix[9], pMatrix[10]); float lrow0 = AglVector3::length(row0); float lrow1 = AglVector3::length(row1); float lrow2 = AglVector3::length(row2); pScale[0] = lrow0; pScale[1] = lrow1; pScale[2] = lrow2; row0 *= (1/lrow0); row1 *= (1/lrow1); row2 *= (1/lrow2); //Translation pTranslation[0] = pMatrix[12]; pTranslation[1] = pMatrix[13]; pTranslation[2] = pMatrix[14]; //Rotation //Find the largest factor. float qx, qy, qz, qw; if (row0[0] + row1[1] + row2[2] > 0.0f) //Use w { float t = row0[0] + row1[1] + row2[2] + pMatrix[15]; float s = 0.5f / sqrt(t); qw = s * t; qz = (row0[1] - row1[0]) * s; qy = (row2[0] - row0[2]) * s; qx = (row1[2] - row2[1]) * s; } else if (row0[0] > row1[1] && row0[0] > row2[2]) //Use x { float t = row0[0] - row1[1] - row2[2] + pMatrix[15]; float s = 0.5f / sqrt(t); qx = s * t; qy = (row0[1] + row1[0]) * s; qz = (row2[0] + row0[2]) * s; qw = (row1[2] - row2[1]) * s; } else if (row1[1] > row2[2]) //Use y { float t = -row0[0] + row1[1] - row2[2] + pMatrix[15]; float s = 0.5f / sqrt(t); qy = s * t; qx = (row0[1] + row1[0]) * s; qw = (row2[0] - row0[2]) * s; qz = (row1[2] + row2[1]) * s; } else //Use z { float t = -row0[0] - row1[1] + row2[2] + pMatrix[15]; float s = 0.5f / sqrt(t); qz = s * t; qw = (row0[1] - row1[0]) * s; qx = (row2[0] + row0[2]) * s; qy = (row1[2] + row2[1]) * s; } pQuaternion = AglQuaternion(qx, qy, qz, qw); }
cv::Mat Deformation::DeformByMovingLeastSquares(const cv::Mat& inputImg, const std::vector<int>& originIndex, const std::vector<int>& targetIndex) { int imgW = inputImg.cols; int imgH = inputImg.rows; cv::Size imgSize(imgW, imgH); cv::Mat resImg(imgSize, CV_8UC3); int markNum = originIndex.size() / 2; std::vector<double> wList(markNum); std::vector<MagicMath::Vector2> pHatList(markNum); std::vector<MagicMath::Vector2> qHatList(markNum); MagicMath::Vector2 pStar, qStar; std::vector<MagicMath::Vector2> pList(markNum); for (int mid = 0; mid < markNum; mid++) { pList.at(mid) = MagicMath::Vector2(originIndex.at(mid * 2), originIndex.at(mid * 2 + 1)); } std::vector<MagicMath::Vector2> qList(markNum); for (int mid = 0; mid < markNum; mid++) { qList.at(mid) = MagicMath::Vector2(targetIndex.at(mid * 2), targetIndex.at(mid * 2 + 1)); } std::vector<std::vector<double> > aMatList(markNum); std::vector<bool> visitFlag(imgW * imgH, 0); for (int hid = 0; hid < imgH; hid++) { for (int wid = 0; wid < imgW; wid++) { MagicMath::Vector2 pos(wid, hid); //calculate w bool isMarkVertex = false; int markedIndex = -1; double wSum = 0; for (int mid = 0; mid < markNum; mid++) { //double dTemp = (pos - pList.at(mid)).LengthSquared(); //variable double dTemp = (pos - pList.at(mid)).Length(); //dTemp = pow(dTemp, 1.25); if (dTemp < 1.0e-15) { isMarkVertex = true; markedIndex = mid; break; } dTemp = pow(dTemp, 1.25); wList.at(mid) = 1.0 / dTemp; wSum += wList.at(mid); } // if (isMarkVertex) { const unsigned char* pPixel = inputImg.ptr(hid, wid); int targetH = targetIndex.at(2 * markedIndex + 1); int targetW = targetIndex.at(2 * markedIndex); unsigned char* pResPixel = resImg.ptr(targetH, targetW); pResPixel[0] = pPixel[0]; pResPixel[1] = pPixel[1]; pResPixel[2] = pPixel[2]; visitFlag.at(targetH * imgW + targetW) = 1; } else { //Calculate pStar qStar pStar = MagicMath::Vector2(0.0, 0.0); qStar = MagicMath::Vector2(0.0, 0.0); for (int mid = 0; mid < markNum; mid++) { pStar += (pList.at(mid) * wList.at(mid)); qStar += (qList.at(mid) * wList.at(mid)); } pStar /= wSum; qStar /= wSum; //Calculate pHat qHat for (int mid = 0; mid < markNum; mid++) { pHatList.at(mid) = pList.at(mid) - pStar; qHatList.at(mid) = qList.at(mid) - qStar; } //Calculate A MagicMath::Vector2 col0 = pos - pStar; MagicMath::Vector2 col1(col0[1], -col0[0]); for (int mid = 0; mid < markNum; mid++) { std::vector<double> aMat(4); MagicMath::Vector2 row1(pHatList.at(mid)[1], -pHatList.at(mid)[0]); aMat.at(0) = pHatList.at(mid) * col0 * wList.at(mid); aMat.at(1) = pHatList.at(mid) * col1 * wList.at(mid); aMat.at(2) = row1 * col0 * wList.at(mid); aMat.at(3) = row1 * col1 * wList.at(mid); aMatList.at(mid) = aMat; } //Calculate fr(v) MagicMath::Vector2 fVec(0, 0); for (int mid = 0; mid < markNum; mid++) { fVec[0] += (qHatList.at(mid)[0] * aMatList.at(mid).at(0) + qHatList.at(mid)[1] * aMatList.at(mid).at(2)); fVec[1] += (qHatList.at(mid)[0] * aMatList.at(mid).at(1) + qHatList.at(mid)[1] * aMatList.at(mid).at(3)); } //Calculate target position fVec.Normalise(); MagicMath::Vector2 targetPos = fVec * ((pos - pStar).Length()) + qStar; int targetW = targetPos[0]; int targetH = targetPos[1]; if (targetH >= 0 && targetH < imgH && targetW >= 0 && targetW < imgW) { const unsigned char* pPixel = inputImg.ptr(hid, wid); unsigned char* pResPixel = resImg.ptr(targetH, targetW); pResPixel[0] = pPixel[0]; pResPixel[1] = pPixel[1]; pResPixel[2] = pPixel[2]; visitFlag.at(targetH * imgW + targetW) = 1; } } } } std::vector<int> unVisitVecH; std::vector<int> unVisitVecW; for (int hid = 0; hid < imgH; hid++) { int baseIndex = hid * imgW; for (int wid = 0; wid < imgW; wid++) { if (!visitFlag.at(baseIndex + wid)) { unVisitVecH.push_back(hid); unVisitVecW.push_back(wid); } } } int minAcceptSize = 4; int fillTime = 1; while (unVisitVecH.size() > 0) { DebugLog << "unVisit number: " << unVisitVecH.size() << std::endl; std::vector<int> unVisitVecHCopy = unVisitVecH; std::vector<int> unVisitVecWCopy = unVisitVecW; unVisitVecH.clear(); unVisitVecW.clear(); int unVisitSize = unVisitVecHCopy.size(); for (int uid = 0; uid < unVisitSize; uid++) { MagicMath::Vector3 avgColor(0, 0, 0); int hid = unVisitVecHCopy.at(uid); int wid = unVisitVecWCopy.at(uid); int avgSize = 0; if ((hid - 1) >= 0 && visitFlag.at((hid - 1) * imgW + wid)) { unsigned char* pPixel = resImg.ptr(hid - 1, wid); avgColor[0] += pPixel[0]; avgColor[1] += pPixel[1]; avgColor[2] += pPixel[2]; avgSize++; } if ((hid + 1) < imgH && visitFlag.at((hid + 1) * imgW + wid)) { unsigned char* pPixel = resImg.ptr(hid + 1, wid); avgColor[0] += pPixel[0]; avgColor[1] += pPixel[1]; avgColor[2] += pPixel[2]; avgSize++; } if ((wid - 1) >= 0 && visitFlag.at(hid * imgW + wid - 1)) { unsigned char* pPixel = resImg.ptr(hid, wid - 1); avgColor[0] += pPixel[0]; avgColor[1] += pPixel[1]; avgColor[2] += pPixel[2]; avgSize++; } if ((wid + 1) < imgW && visitFlag.at(hid * imgW + wid + 1)) { unsigned char* pPixel = resImg.ptr(hid, wid + 1); avgColor[0] += pPixel[0]; avgColor[1] += pPixel[1]; avgColor[2] += pPixel[2]; avgSize++; } if (avgSize >= minAcceptSize) { visitFlag.at(hid * imgW + wid) = 1; avgColor /= avgSize; unsigned char* pFillPixel = resImg.ptr(hid, wid); pFillPixel[0] = avgColor[0]; pFillPixel[1] = avgColor[1]; pFillPixel[2] = avgColor[2]; } else { unVisitVecH.push_back(hid); unVisitVecW.push_back(wid); } } if (fillTime == 4) { minAcceptSize--; } else if (fillTime == 6) { minAcceptSize--; } else if (fillTime == 8) { minAcceptSize--; } fillTime++; } //fill hole /*for (int hid = 0; hid < imgH; hid++) { int baseIndex = hid * imgW; for (int wid = 0; wid < imgW; wid++) { if (!visitFlag.at(baseIndex + wid)) { double wSum = 0; MagicMath::Vector3 avgColor(0, 0, 0); for (int wRight = wid + 1; wRight < imgW; wRight++) { if (visitFlag.at(baseIndex + wRight)) { double wTemp = 1.0 / (wRight - wid); wSum += wTemp; unsigned char* pPixel = resImg.ptr(hid, wRight); avgColor[0] += wTemp * pPixel[0]; avgColor[1] += wTemp * pPixel[1]; avgColor[2] += wTemp * pPixel[2]; break; } } for (int wLeft = wid - 1; wLeft >= 0; wLeft--) { if (visitFlag.at(baseIndex + wLeft)) { double wTemp = 1.0 / (wid - wLeft); wSum += wTemp; unsigned char* pPixel = resImg.ptr(hid, wLeft); avgColor[0] += wTemp * pPixel[0]; avgColor[1] += wTemp * pPixel[1]; avgColor[2] += wTemp * pPixel[2]; break; } } for (int hUp = hid - 1; hUp >= 0; hUp--) { if (visitFlag.at(hUp * imgW + wid)) { double wTemp = 1.0 / (hid - hUp); unsigned char* pPixel = resImg.ptr(hUp, wid); wSum += wTemp; avgColor[0] += wTemp * pPixel[0]; avgColor[1] += wTemp * pPixel[1]; avgColor[2] += wTemp * pPixel[2]; break; } } for (int hDown = hid + 1; hDown < imgH; hDown++) { if (visitFlag.at(hDown * imgW + wid)) { double wTemp = 1.0 / (hDown - hid); unsigned char* pPixel = resImg.ptr(hDown, wid); wSum += wTemp; avgColor[0] += wTemp * pPixel[0]; avgColor[1] += wTemp * pPixel[1]; avgColor[2] += wTemp * pPixel[2]; break; } } if (wSum > 1.0e-15) { avgColor /= wSum; } unsigned char* pFillPixel = resImg.ptr(hid, wid); pFillPixel[0] = avgColor[0]; pFillPixel[1] = avgColor[1]; pFillPixel[2] = avgColor[2]; } } }*/ return resImg; }
/* Derivation from the fortran version of CONREC by Paul Bourke view ! view of the data ilb,iub ! bounds for first coordinate (column), inclusive jlb,jub ! bounds for second coordinate (row), inclusive xCoords ! column coordinates (first index) yCoords ! row coordinates (second index) nc ! number of contour levels z ! contour levels in increasing order */ static Carta::Lib::Algorithms::ContourConrec::Result conrecFaster( Carta::Lib::NdArray::RawViewInterface * view, int ilb, int iub, int jlb, int jub, const VD & xCoords, const VD & yCoords, int nc, double * z ) { // we will only need two rows in memory at any given time // int nRows = jub - jlb + 1; int nCols = iub - ilb + 1; double * rows[2] { nullptr, nullptr }; std::vector < double > row1( nCols ), row2( nCols ); rows[0] = & row1[0]; rows[1] = & row2[0]; int nextRowToReadIn = 0; auto updateRows = [&] () -> void { CARTA_ASSERT( nextRowToReadIn < view-> dims()[1] ); // make a row view into the view SliceND rowSlice; rowSlice.next().start( nextRowToReadIn ).end( nextRowToReadIn + 1 ); auto rawRowView = view-> getView( rowSlice ); nextRowToReadIn++; // make a double view of this raw row view Carta::Lib::NdArray::Double dview( rawRowView, true ); // shift the row up // note: we could avoid this memory copy if we swapped row[] pointers instead, // and alternately read in the data into row1,row2..., for a miniscule performance // gain and lot more complicated algorithm row1 = row2; // read in the data into row2 int i = 0; dview.forEach([&] ( const double & val ) { row2[i++] = val; } ); CARTA_ASSERT( i == nCols ); }; updateRows(); // NdArray::Double doubleView( view, false ); // auto acc = [& doubleView] ( int col, int row ) { // return doubleView.get( { col, row } // ); // }; // to keep the data accessor easy, we use this lambda, and hope the compiler // optimizes it into an inline expression... :) auto acc = [&] ( int col, int row ) { row -= nextRowToReadIn - 2; return rows[row][col]; }; Carta::Lib::Algorithms::ContourConrec::Result result; if ( nc < 1 ) { return result; } result.resize( nc ); #define xsect( p1, p2 ) ( h[p2] * xh[p1] - h[p1] * xh[p2] ) / ( h[p2] - h[p1] ) #define ysect( p1, p2 ) ( h[p2] * yh[p1] - h[p1] * yh[p2] ) / ( h[p2] - h[p1] ) int m1, m2, m3, case_value; double dmin, dmax, x1 = 0, x2 = 0, y1 = 0, y2 = 0; int i, j, k, m; double h[5]; int sh[5]; double xh[5], yh[5]; int im[4] = { 0, 1, 1, 0 }, jm[4] = { 0, 0, 1, 1 }; int castab[3][3][3] = { { { 0, 0, 8 }, { 0, 2, 5 }, { 7, 6, 9 } }, { { 0, 3, 4 }, { 1, 3, 1 }, { 4, 3, 0 } }, { { 9, 6, 7 }, { 5, 2, 0 }, { 8, 0, 0 } } }; double temp1, temp2; // original code went from bottom to top, not sure why // for ( j = ( jub - 1 ) ; j >= jlb ; j-- ) { for ( j = jlb ; j < jub ; j++ ) { updateRows(); for ( i = ilb ; i < iub ; i++ ) { temp1 = std::min( acc( i, j ), acc( i, j + 1 ) ); temp2 = std::min( acc( i + 1, j ), acc( i + 1, j + 1 ) ); dmin = std::min( temp1, temp2 ); // early abort if one of the values is not finite if ( ! std::isfinite( dmin ) ) { continue; } temp1 = std::max( acc( i, j ), acc( i, j + 1 ) ); temp2 = std::max( acc( i + 1, j ), acc( i + 1, j + 1 ) ); dmax = std::max( temp1, temp2 ); if ( dmax < z[0] || dmin > z[nc - 1] ) { continue; } for ( k = 0 ; k < nc ; k++ ) { if ( z[k] < dmin || z[k] > dmax ) { continue; } for ( m = 4 ; m >= 0 ; m-- ) { if ( m > 0 ) { h[m] = acc( i + im[m - 1], j + jm[m - 1] ) - z[k]; xh[m] = xCoords[i + im[m - 1]]; yh[m] = yCoords[j + jm[m - 1]]; } else { h[0] = 0.25 * ( h[1] + h[2] + h[3] + h[4] ); xh[0] = 0.50 * ( xCoords[i] + xCoords[i + 1] ); yh[0] = 0.50 * ( yCoords[j] + yCoords[j + 1] ); } if ( h[m] > 0.0 ) { sh[m] = 1; } else if ( h[m] < 0.0 ) { sh[m] = - 1; } else { sh[m] = 0; } } /* Note: at this stage the relative heights of the corners and the centre are in the h array, and the corresponding coordinates are in the xh and yh arrays. The centre of the box is indexed by 0 and the 4 corners by 1 to 4 as shown below. Each triangle is then indexed by the parameter m, and the 3 vertices of each triangle are indexed by parameters m1,m2,and m3. It is assumed that the centre of the box is always vertex 2 though this isimportant only when all 3 vertices lie exactly on the same contour level, in which case only the side of the box is drawn. vertex 4 +-------------------+ vertex 3 | \ / | | \ m-3 / | | \ / | | \ / | | m=2 X m=2 | the centre is vertex 0 | / \ | | / \ | | / m=1 \ | | / \ | vertex 1 +-------------------+ vertex 2 */ /* Scan each triangle in the box */ for ( m = 1 ; m <= 4 ; m++ ) { m1 = m; m2 = 0; if ( m != 4 ) { m3 = m + 1; } else { m3 = 1; } if ( ( case_value = castab[sh[m1] + 1][sh[m2] + 1][sh[m3] + 1] ) == 0 ) { continue; } switch ( case_value ) { case 1 : /* Line between vertices 1 and 2 */ x1 = xh[m1]; y1 = yh[m1]; x2 = xh[m2]; y2 = yh[m2]; break; case 2 : /* Line between vertices 2 and 3 */ x1 = xh[m2]; y1 = yh[m2]; x2 = xh[m3]; y2 = yh[m3]; break; case 3 : /* Line between vertices 3 and 1 */ x1 = xh[m3]; y1 = yh[m3]; x2 = xh[m1]; y2 = yh[m1]; break; case 4 : /* Line between vertex 1 and side 2-3 */ x1 = xh[m1]; y1 = yh[m1]; x2 = xsect( m2, m3 ); y2 = ysect( m2, m3 ); break; case 5 : /* Line between vertex 2 and side 3-1 */ x1 = xh[m2]; y1 = yh[m2]; x2 = xsect( m3, m1 ); y2 = ysect( m3, m1 ); break; case 6 : /* Line between vertex 3 and side 1-2 */ x1 = xh[m3]; y1 = yh[m3]; x2 = xsect( m1, m2 ); y2 = ysect( m1, m2 ); break; case 7 : /* Line between sides 1-2 and 2-3 */ x1 = xsect( m1, m2 ); y1 = ysect( m1, m2 ); x2 = xsect( m2, m3 ); y2 = ysect( m2, m3 ); break; case 8 : /* Line between sides 2-3 and 3-1 */ x1 = xsect( m2, m3 ); y1 = ysect( m2, m3 ); x2 = xsect( m3, m1 ); y2 = ysect( m3, m1 ); break; case 9 : /* Line between sides 3-1 and 1-2 */ x1 = xsect( m3, m1 ); y1 = ysect( m3, m1 ); x2 = xsect( m1, m2 ); y2 = ysect( m1, m2 ); break; default : break; } // switch // add the line segment to the result // ConrecLine( x1, y1, x2, y2, k ); if ( std::isfinite( x1 ) && std::isfinite( y1 ) && std::isfinite( x2 ) && std::isfinite( y2 ) ) { QPolygonF poly; poly.append( QPointF( x1, y1 ) ); poly.append( QPointF( x2, y2 ) ); result[k].push_back( poly ); } } /* m */ } /* k - contour */ } /* i */ } /* j */ return result; #undef xsect #undef ysect } // conrecFaster