double FE(double deltaEta, int index) { Approximator* app = new EulerApprox( (sysdiffeq) Yamabe, "r3"); Eta* eta = Eta::At(Triangulation::edgeTable[index]); double curEta = eta->getValue(); eta->setValue(curEta + deltaEta); vector<double> radii; vector<double> curvs; double initRadii[Triangulation::vertexTable.size()]; double dt = 0.030; double precision = 0.000000001; getRadii(initRadii); app->run(precision, dt); double result = F(); eta->setValue(curEta); setRadii(initRadii); return result; }
int main(int argc, char * const argv[]) { bool steps = false; string stepPrefix = "/tmp/steps"; bool approximate = false; string approximationFilename; typedef uint8_t C; typedef ColorImage<C> ColorImage; typedef shared_ptr<ColorImage> ColorImageRef; typedef RGBPixel<C> RGBPixel; typedef GreyImage<C> GreyImage; typedef shared_ptr<GreyImage> GreyImageRef; typedef PenColor<C> PenColor; typedef Pen<C> Pen; typedef Carousel<C> Carousel; Carousel carousel; list< Output<Pen>* > outputs; int argn = 1; size_t equals = string::npos; Rotation rotation = None; int offsetX = 0, offsetY = 0; double scale = 1.0; bool dither = true; int threads = 1; for (; argn < argc && argv[argn][0] == '-' && strlen(argv[argn]) > 1; argn++) { string arg(argv[argn]); D(cerr << "arg[" << argn << "] == '" << arg << "'" << endl << flush); string penSpec; if (0 == arg.find("-pen")) { Pen pen; if (4 == arg.find("=")) { penSpec = arg.substr(5); } else { ++argn; if (!(argn < argc)) { cerr << "missing argument to '-pen'" << endl << flush; exit(1); } penSpec = argv[argn]; } size_t start = 0; while (start != string::npos) { D(cerr << "start=" << start << endl << flush); size_t comma = penSpec.find(',', start); string part; if (comma != string::npos) { part = penSpec.substr(start, comma - start); start = comma + 1; } else { part = penSpec.substr(start); start = string::npos; } D(cerr << "part='" << part << "'" << endl << flush); if ((equals = part.find('=')) == string::npos) { cerr << "pen specification part '" << part << "' missing '='" << endl << flush; exit(1); } else { string name = part.substr(0, equals); string value = part.substr(equals + 1); D(cerr << "name='" << name << "', value='" << value << "'" << endl << flush); switch(name[0]) { case 'c': // colour pen.color() = PenColor::parse(value); break; case 'r': // radius pen.r() = getInt(value); break; case 'm': // minimum size that can be drawn pen.rMin() = getInt(value); break; case 'i': // HPGL Index pen.hpglIndex() = getInt(value); break; case 'a': // hatch angle pen.hatchAngle() = getDouble(value); break; case 'p': // hatch phase pen.hatchPhase() = getDouble(value); break; } } } // now add this pen to the carousel carousel.addPen(pen); } else if (0 == arg.find("-rotate")) { string rotationSpec; if (7 == arg.find("=")) { rotationSpec = arg.substr(8); } else { ++argn; if (!(argn < argc)) { cerr << "missing argument to '-rotate'" << endl << flush; exit(1); } rotationSpec = argv[argn]; } switch (rotationSpec[0]) { case 'l': case 'L': rotation = Left; break; case 'r': case 'R': rotation = Right; break; case 'u': case 'U': rotation = UpsideDown; break; default: cerr << "unrecognized rotation '" << arg << "'" << endl << flush; exit(1); } } else if (0 == arg.find("-offset")) { string offset; if (7 == arg.find("=")) { offset = arg.substr(8); } else { ++argn; if (!(argn < argc)) { cerr << "missing argument to '-offset'" << endl << flush; exit(1); } offset = argv[argn]; } size_t delim = offset.find_first_of("x,"); if (delim == string::npos) { // no delimiter - offset both x & y by the same amount offsetX = offsetY = getInt(offset); } else { offsetX = getInt(offset.substr(0, delim)); offsetY = getInt(offset.substr(delim+1)); } } else if (0 == arg.find("-steps")) { steps = true; if (6 == arg.find("=")) { stepPrefix = arg.substr(7); } } else if (0 == arg.find("-approx")) { approximate = true; if (7 == arg.find("=")) { approximationFilename = arg.substr(8); } else { approximationFilename = "approximation.png"; } } else if (0 == arg.find("-nodither")) { dither = false; } else if (0 == arg.find("-out")) { size_t eqPos; string outputFile; if (string::npos != (eqPos = arg.find("="))) { outputFile = arg.substr(eqPos + 1); arg = arg.substr(0, eqPos); } else { ++argn; if (!(argn < argc)) { cerr << "missing argument to '" << arg << "'" << endl << flush; exit(1); } outputFile = argv[argn]; } string outputType = arg.substr(4); if (0 == outputType.length()) { outputType = "ha"; // HPGL, absolute coordinates } std::transform(outputType.begin(), outputType.end(), outputType.begin(), ::tolower); outputs.push_back(makeOutput<Pen>(outputType, outputFile)); } else if (0 == arg.find("-scale")) { string scaleString; if (6 == arg.find("=")) { scaleString = arg.substr(7); } else { ++argn; if (!(argn < argc)) { cerr << "missing argument to '-scale'" << endl << flush; exit(1); } scaleString = argv[argn]; } scale = getDouble(scaleString); } else if (0 == arg.find("-threads")) { string threadsArg; if (8 == arg.find("=")) { threadsArg = arg.substr(9); } else { ++argn; if (!(argn < argc)) { cerr << "missing argument to '-threads'" << endl << flush; exit(1); } threadsArg = argv[argn]; } threads = getInt(threadsArg); } else { cerr << "Unrecognized argument '" << arg << "'" << endl << flush; exit(1); } } string inputFile; if (argn == argc - 1) { inputFile = argv[argn]; } else if (argn == argc) { // default: is inputFile = "-"; } else { cerr << "Extra arguments after input file '" << argv[argn] << "'!"; cerr << endl << flush; exit(1); } // If there's no specified carousel, use a default one. if (carousel.size() == 0) { cerr << "No pens specified, using default carousel" << endl << flush; // populate the carousel with a default set of pens: // black, red, green blue, cyan, magenta, yellow, orange; // each at 0.35 mm diameter = 0.175 mm radius = 7 units radius Pen black(1.0, 1.0, 1.0, 3); black.hpglIndex() = 1; black.hatchAngle() = 1.0 / 25.0; Pen red(0.0, 1.0, 1.0, 3); red.hpglIndex() = 2; red.hatchAngle() = 4.0 / 25.0; Pen green(1.0, 0.0, 1.0, 3); green.hpglIndex() = 3; green.hatchAngle() = 7.0 / 25.0; Pen blue(1.0, 1.0, 0.0, 3); blue.hpglIndex() = 4; blue.hatchAngle() = 10.0 / 25.0; Pen orange(0.0, 0.5, 1.0, 3); orange.hpglIndex() = 8; orange.hatchAngle() = 13.0 / 25.0; Pen cyan(1.0, 0.0, 0.0, 3); cyan.hpglIndex() = 5; cyan.hatchAngle() = 16.0 / 25.0; Pen magenta(0.0, 1.0, 0.0, 3); magenta.hpglIndex() = 6; magenta.hatchAngle() = 19.0 / 25.0; Pen yellow(0.0, 0.0, 1.0, 3); yellow.hpglIndex() = 7; yellow.hatchAngle() = 22.0 / 25.0; // put the pens into the carousel in a suitable order carousel.addPen(black); carousel.addPen(orange); carousel.addPen(red); carousel.addPen(green); carousel.addPen(blue); carousel.addPen(cyan); carousel.addPen(magenta); carousel.addPen(yellow); } // if there's no output specified, use a default one. if (outputs.size() == 0) { cerr << "No output specified, writing HPGL to standard output" << endl << flush; outputs.push_back(new HPGLAbsoluteOutput<Pen>(cout)); } FILE *f; if ("-" == inputFile) { cerr << "* Reading image from standard input" << endl << flush; f = stdin; } else { cerr << "* Reading image '" << inputFile << "'" << endl << flush; f = fopen(inputFile.c_str(), "r"); if (f == NULL) { cerr << "unable to open input file '" << inputFile << "'!" << endl << flush; exit(1); } } ColorImageRef colored(ColorImage::readPng(f)); if (scale != 1.0) { colored = scaleImage(colored, scale); } Approximator *approximator = NULL; if (approximate) { approximator = new Approximator(colored->width(), colored->height()); approximator->approximation().copyRes(colored); RGBPixel whitePixel(1.0, 1.0, 1.0); approximator->approximation().setAll(whitePixel); } map<Pen, Chains> ditheredByPen; double dTheta = 1.0 / carousel.size(); double theta = 0.1; PlotterPathExtractor extractor; shared_ptr<Workers> workers = make_shared<Workers>(threads); extractor.setOut(&cerr); extractor.setDither(dither); extractor.setWorkers(workers); Stepper *stepper; if (steps) { extractor.setStepper(stepper = new Stepper(stepPrefix)); } if (approximate) { extractor.setApproximator(approximator); } int p = 0; for (Carousel::iterator c = carousel.begin(); c != carousel.end(); ++c) { const PenColor &color = *c; cerr << "- Separating out colour " << color << endl; GreyImageRef separated = colored->separateAndSubtract(color); if (steps) { cerr << " . writing separation" << endl; separated->writePng(stepper->makeName("separation.png", color.unparse().c_str())); } if (approximate) { approximator->setPenColor(color); } list<Pen> &pens = carousel.pensWithColor(color); extractor.outlineHatchThinDither(separated, pens, ditheredByPen); ++p; theta += dTheta; } IMatrix transform = IMatrix::identity(); cerr << "initial transform: " << transform << endl << flush; cerr << "offsetX = " << offsetX << ", offsetY = " << offsetY << endl << flush; if (offsetX != 0 || offsetY != 0) { transform = transform.concat(IMatrix::translate(offsetX, offsetY)); } cerr << "after offset: " << transform << endl << flush; cerr << "rotation = " << rotation << endl << flush; if (rotation == Left) { transform = transform.concat(IMatrix::pageLeft(colored->width(), colored->height())); } else if (rotation == Right) { transform = transform.concat(IMatrix::pageRight(colored->width(), colored->height())); } else if (rotation == UpsideDown) { transform = transform.concat(IMatrix::pageUpsideDown(colored->width(), colored->height())); } cerr << "after rotation: " << transform << endl << flush; int maxX = numeric_limits<int>::min(), maxY = numeric_limits<int>::min(); int minX = numeric_limits<int>::max(), minY = numeric_limits<int>::max(); for (int x = 0; x < colored->width(); x += colored->width()-1) { for (int y = 0; y < colored->height(); y += colored->height()-1) { IPoint p(x, y); p.transform(transform); minX = min(p.x(), minX); maxX = max(p.x(), maxX); minY = min(p.y(), minY); maxY = max(p.y(), maxY); } } cerr << "minX = " << minX << ", minY = " << minY << ", maxX = " << maxX << ", maxY = " << maxY << endl << flush; // Finally, adjust for the top-to-bottom Y of our bitmaps // vs the bottom-to-top Y of our output devices IMatrix adjustment(1, 0, 0, -1, 0, colored->height()); transform = transform.concat(adjustment); cerr << "after adjustment: " << transform << endl << flush; for (list< Output<Pen>* >::const_iterator outIter = outputs.begin(); outIter != outputs.end(); ++outIter) { cerr << "Writing " << (**outIter) << endl << flush; (*outIter)->open(); (*outIter)->beginPage(maxX + 1, maxY + 1); } for (map<Pen, Chains>::iterator di = ditheredByPen.begin(); di != ditheredByPen.end(); ++di) { const Pen &pen = di->first; Chains &dithered = di->second; if (transform != IMatrix::identity()) { cerr << "- applying transform " << transform << endl << flush; dithered.transform(transform); } else { cerr << "- skipping identity transform " << transform << endl << flush; } for (list< Output<Pen>* >::const_iterator outIter = outputs.begin(); outIter != outputs.end(); ++outIter) { (*outIter)->setPen(pen); (*outIter)->outputChains(dithered); } } for (list< Output<Pen>* >::const_iterator outIter = outputs.begin(); outIter != outputs.end(); ++outIter) { (*outIter)->endPage(); (*outIter)->close(); delete (*outIter); } outputs.clear(); if (approximate) { cerr << " . drawing final approximation" << endl; approximator->approximation().writePng(approximationFilename.c_str()); delete approximator; approximator = NULL; } }
int ribi::tapx::MenuDialog::ExecuteSpecific(const std::vector<std::string>& /*argv*/) noexcept { //Use Boost.Units to thoroughly check if Approximation is a good template: //If it even compiles with Boost.Units, it probably is { typedef boost::units::quantity<boost::units::si::time> Time; typedef boost::units::quantity<boost::units::si::velocity> Velocity; Approximator<Time,Velocity> a; a.Add(0.0 * boost::units::si::second,0.0 * boost::units::si::meters_per_second); a.Add(2.0 * boost::units::si::second,2.0 * boost::units::si::meters_per_second); #ifndef NDEBUG const Velocity v = a.Approximate(1.0 * boost::units::si::second); assert(v >= 0.99 * boost::units::si::meters_per_second && v <= 1.01 * boost::units::si::meters_per_second); #endif } typedef Approximator<double,int> Approximator_t; Approximator_t a; a.Add(20, 5); a.Add(30,15); a.Add(40, 5); a.Add(50,15); const int max_x = 78; const int max_y = 20; DrawCanvas c( max_x, max_y, CanvasColorSystem::invert, CanvasCoordinatSystem::graph ); c.DrawLine(0.0,0.0,max_x,0.0); c.DrawLine(0.0,0.0,0.0,max_y); //Plot values (note: these won't be visible in Canvas) { std::vector<double> xs; std::vector<double> ys; for (const auto& p: a.Get()) { c.DrawDot( static_cast<double>(p.first), static_cast<double>(p.second) ); } } //Plot approximation { for (int t=0; t != max_x; ++t) { try { const double x = static_cast<double>(t); const double y = a.Approximate(x); c.DrawDot(x,y); } catch (ExceptionNoExtrapolation<Approximator_t::key_type>& e) { //X value not in range. OK not to plot then... } } } std::cout << c << std::endl; return 0; }
int main(int argc, char** argv) { map<int, Vertex>::iterator vit; map<int, Edge>::iterator eit; map<int, Face>::iterator fit; vector<int> edges; vector<int> faces; time_t start, end; // File to read in triangulation from. char from[] = "Data/2DManifolds/LutzFormat/domain2.txt"; // File to convert to proper format. char to[] = "Data/2DManifolds/StandardFormat/domain2.txt"; // Convert, then read in triangulation. makeTriangulationFile(from, to); readTriangulationFileWithData(to); writeTriangulationFile("fudge.txt"); int vertSize = Triangulation::vertexTable.size(); int edgeSize = Triangulation::edgeTable.size(); int faceSize = Triangulation::faceTable.size(); // Set the radii and alphas for(int i = 1; i <= vertSize; i++) { Radius::At(Triangulation::vertexTable[i])->setValue(1.0 ) ; Alpha::At(Triangulation::vertexTable[i])->setValue(0.0 ); printf("alph= %f\n",Alpha::valueAt(Triangulation::vertexTable[i])); } Radius::At(Triangulation::vertexTable[6])->setValue(1.0 ) ; Radius::At(Triangulation::vertexTable[7])->setValue(1.0 ) ; Radius::At(Triangulation::vertexTable[8])->setValue(1.2 ) ; Radius::At(Triangulation::vertexTable[9])->setValue(90.0 ) ; Alpha::At(Triangulation::vertexTable[9])->setValue(1.0 ) ; // Set the etas // for(int i = 1; i <= edgeSize; i++) { // if ((Triangulation::edgeTable[i]).isAdjVertex(9)) { // Eta::At(Triangulation::edgeTable[i])->setValue(-1.0);} // else { // Eta::At(Triangulation::edgeTable[i])->setValue(1.0);} // printf("%f\n",Eta::valueAt(Triangulation::edgeTable[i])); // } for(int i = 1; i <= edgeSize; i++) { if ((Triangulation::edgeTable[i]).isAdjVertex(9)) { Eta::At(Triangulation::edgeTable[i])->setValue(0.0);} else { Eta::At(Triangulation::edgeTable[i])->setValue(1.0);} } Eta::At(Triangulation::edgeTable[2])->setValue(0.5); Eta::At(Triangulation::edgeTable[3])->setValue(0.5); Eta::At(Triangulation::edgeTable[5])->setValue(0.5); Eta::At(Triangulation::edgeTable[7])->setValue(0.5); Eta::At(Triangulation::edgeTable[8])->setValue(4.5); Eta::At(Triangulation::edgeTable[9])->setValue(2.5); Eta::At(Triangulation::edgeTable[10])->setValue(2.0); Eta::At(Triangulation::edgeTable[13])->setValue(4.5); Eta::At(Triangulation::edgeTable[14])->setValue(5.0); Eta::At(Triangulation::edgeTable[15])->setValue(2.0); Eta::At(Triangulation::edgeTable[16])->setValue(0.5); // Construct an Approximator object that uses the Euler method and Ricci flow while // recording radii, curvatures. for(int i = 1; i <= faceSize; i++) { if ((Triangulation::faceTable[i]).isAdjVertex(9)) { (Triangulation::faceTable[i]).setNegativity(true); printf("hi");} } writeTriangulationFileWithData("initdata.txt"); printf("degree of 1 =%d\n",(Triangulation::vertexTable[1]).getDegree()); Approximator *app = new EulerApprox((sysdiffeq) Ricci, "rfnew"); // Run the flow with precision and accuracy bounds of 0.0001 and stepsize of 0.01 app->run(6000, 0.001); writeTriangulationFileWithData("trydata.txt"); // Print out radii, curvatures and volumes printResultsStep("./ODE Result.txt", &(app->radiiHistory), &(app->curvHistory)); system("Pause"); return 0; }
void ribi::QtToolTestMultiApproximatorMainDialog::Plot() noexcept { //Plot multi approximation { //Plot raw data { std::vector<double> xs; std::vector<double> ys; for (const auto p: m_multi_approximator.GetContainer()) { xs.push_back( static_cast<double>(p.first) ); ys.push_back( static_cast<double>(p.second) ); } assert(m_curve_multi_values); #if QWT_VERSION >= 0x060000 m_curve_multi_values->setData(new QwtPointArrayData(&xs[0],&ys[0],xs.size())); #else m_curve_values->setData(&xs[0],&y[0],xs.size()); #endif } const double min_x = static_cast<double>(ui->box_int_x->minimum()); const double max_x = static_cast<double>(ui->box_int_x->maximum()); //Plot approximation { std::vector<double> xs; std::vector<double> ys; for (double t=min_x; t < max_x; t+=0.5) { try { const double x = static_cast<double>(t); const MultiApproximator_t::value_type y = m_multi_approximator.Approximate(x); ys.push_back(y); xs.push_back(x); } catch (ExceptionNoExtrapolation<MultiApproximator_t::key_type>& e) { } } assert(m_curve_multi_approximation); #if QWT_VERSION >= 0x060000 m_curve_multi_approximation->setData(new QwtPointArrayData(&xs[0],&ys[0],xs.size())); #else m_curve_multi_approximation->setData(&xs[0],&y[0],xs.size()); #endif } assert(m_multi_plot); m_multi_plot->replot(); } //Plot (non-multi)approximation { const Approximator<Key,Value,Container> approximator = ToApproximator<Key,Value,MultiContainer,Container>(m_multi_approximator); //Plot raw data { std::vector<double> xs; std::vector<double> ys; for (const auto p: approximator.Get()) { xs.push_back( static_cast<double>(p.first) ); ys.push_back( static_cast<double>(p.second) ); } assert(m_curve_values); #if QWT_VERSION >= 0x060000 m_curve_values->setData(new QwtPointArrayData(&xs[0],&ys[0],xs.size())); #else m_curve_values->setData(&xs[0],&y[0],xs.size()); #endif } const double min_x = static_cast<double>(ui->box_int_x->minimum()); const double max_x = static_cast<double>(ui->box_int_x->maximum()); //Plot approximation { std::vector<double> xs; std::vector<double> ys; for (double t=min_x; t < max_x; t+=0.5) { try { const double x = static_cast<double>(t); const Approximator_t::value_type y = approximator.Approximate(x); ys.push_back(y); xs.push_back(x); } catch (ExceptionNoExtrapolation<Approximator_t::key_type>& e) { } } assert(m_curve_approximation); #if QWT_VERSION >= 0x060000 m_curve_approximation->setData(new QwtPointArrayData(&xs[0],&ys[0],xs.size())); #else m_curve_approximation->setData(&xs[0],&y[0],xs.size()); #endif } assert(m_plot); m_plot->replot(); } }
void MinMax(double deltaEta, double b, double a) { Approximator* app = new EulerApprox( (sysdiffeq) Yamabe, "r3"); char results[] = "Triangulation Files/ODE Result.txt"; FILE* result = fopen(results, "w"); map<int, double> deltaFE; map<int, Edge>::iterator eit; map<int, Tetra>::iterator tit; double initRadii[Triangulation::vertexTable.size()]; double dt = 0.030; double precision = 0.000000001; for(eit = Triangulation::edgeTable.begin(); eit != Triangulation::edgeTable.end(); eit++) { deltaFE.insert(pair<int, double>(eit->first, 0)); } map<int, double>::iterator dfit; app->run(precision, dt); printf("F = %.10f\n", F()); calcDeltaFE(&deltaFE, deltaEta); double length = 0; for(dfit = (deltaFE).begin(); dfit != (deltaFE).end(); dfit++) { // printf("MinMax FE: Index = %3d, Value = %.10f\n", dfit->first, dfit->second); length += pow(dfit->second, 2); } length = sqrt(length); printf("\nGradient Length: %.10f\n", length); printf("\n"); updateEtas(&deltaFE, b, a); printData(result); while(true) { for(eit = Triangulation::edgeTable.begin(); eit != Triangulation::edgeTable.end(); eit++) { printf("Edge %3d: %.10f\n", eit->first, Eta::valueAt(eit->second)); } double totalvolume=0; for(tit = Triangulation::tetraTable.begin(); tit != Triangulation::tetraTable.end(); tit++) { printf("Tetrahedron %d: %.10f\n", tit->first, Volume::valueAt(tit->second)); totalvolume += Volume::valueAt(tit->second) ; } printf("Total Volume = %.10f\n", totalvolume); //updateEtas(&deltaFE, b); //printData(result); //updateEtas(&deltaFE, b); getRadii(initRadii); printf("\n*** *** *** *** *** *** *** *** *** *** ***\n"); app->run(precision, dt); printf("\nF = %.10f\n", F()); printData(result); map<int, Vertex>::iterator vvvit; for(vvvit = Triangulation::vertexTable.begin(); vvvit != Triangulation::vertexTable.end(); vvvit++) { double curv = Curvature3D::valueAt(vvvit->second); printf("vertex %3d: %f\t%.10f\n", vvvit->first, Radius::valueAt(vvvit->second), curv/(Radius::valueAt(vvvit->second))); } calcDeltaFE(&deltaFE, deltaEta); updateEtas(&deltaFE, b, a); printf("\n"); } }