You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

130 lines
3.8 KiB

  1. //
  2. // LolRemez - Remez algorithm implementation
  3. //
  4. // Copyright © 2005—2016 Sam Hocevar <sam@hocevar.net>
  5. //
  6. // This program is free software. It comes without any warranty, to
  7. // the extent permitted by applicable law. You can redistribute it
  8. // and/or modify it under the terms of the Do What the Fuck You Want
  9. // to Public License, Version 2, as published by the WTFPL Task Force.
  10. // See http://www.wtfpl.net/ for more details.
  11. //
  12. #if HAVE_CONFIG_H
  13. # include "config.h"
  14. #endif
  15. #include <lol/engine.h>
  16. #include <lol/math/real.h>
  17. #include "solver.h"
  18. #include "expression.h"
  19. using lol::array;
  20. using lol::real;
  21. using lol::String;
  22. static void version(void)
  23. {
  24. printf("lolremez %s\n", PACKAGE_VERSION);
  25. printf("Copyright © 2005—2016 Sam Hocevar <sam@hocevar.net>\n");
  26. printf("This program is free software. It comes without any warranty, to the extent\n");
  27. printf("permitted by applicable law. You can redistribute it and/or modify it under\n");
  28. printf("the terms of the Do What the Fuck You Want to Public License, Version 2, as\n");
  29. printf("published by the WTFPL Task Force. See http://www.wtfpl.net/ for more details.\n");
  30. printf("\n");
  31. printf("Written by Sam Hocevar. Report bugs to <sam@hocevar.net>.\n");
  32. }
  33. static void usage()
  34. {
  35. printf("Usage: lolremez [-d degree] [-r xmin:xmax] x-expression [x-error]\n");
  36. printf(" lolremez -h | --help\n");
  37. printf(" lolremez -V | --version\n");
  38. printf("Find a polynomial approximation for x-expression.\n");
  39. printf("\n");
  40. printf("Mandatory arguments to long options are mandatory for short options too.\n");
  41. printf(" -d, --degree <degree> degree of final polynomial\n");
  42. printf(" -r, --range <xmin>:<xmax> range over which to approximate\n");
  43. printf(" -h, --help display this help and exit\n");
  44. printf(" -V, --version output version information and exit\n");
  45. printf("\n");
  46. printf("Examples:\n");
  47. printf(" lolremez -d 4 -r -1:1 \"atan(exp(1+x))\"\n");
  48. printf(" lolremez -d 4 -r -1:1 \"atan(exp(1+x))\" \"exp(1+x)\"\n");
  49. printf("\n");
  50. printf("Written by Sam Hocevar. Report bugs to <sam@hocevar.net>.\n");
  51. }
  52. static void FAIL(char const *message = nullptr)
  53. {
  54. if (message)
  55. printf("Error: %s\n", message);
  56. printf("Try 'lolremez --help' for more information.\n");
  57. exit(EXIT_FAILURE);
  58. }
  59. /* See the tutorial at http://lolengine.net/wiki/doc/maths/remez */
  60. int main(int argc, char **argv)
  61. {
  62. String xmin("-1"), xmax("1");
  63. char const *f = nullptr, *g = nullptr;
  64. int degree = 4;
  65. lol::getopt opt(argc, argv);
  66. opt.add_opt('h', "help", false);
  67. opt.add_opt('v', "version", false);
  68. opt.add_opt('d', "degree", true);
  69. opt.add_opt('r', "range", true);
  70. for (;;)
  71. {
  72. int c = opt.parse();
  73. if (c == -1)
  74. break;
  75. switch (c)
  76. {
  77. case 'd': /* --degree */
  78. degree = atoi(opt.arg);
  79. break;
  80. case 'r': { /* --range */
  81. array<String> arg = String(opt.arg).split(':');
  82. if (arg.count() != 2)
  83. FAIL("invalid range");
  84. xmin = arg[0];
  85. xmax = arg[1];
  86. } break;
  87. case 'h': /* --help */
  88. usage();
  89. return EXIT_SUCCESS;
  90. case 'v': /* --version */
  91. version();
  92. return EXIT_SUCCESS;
  93. default:
  94. FAIL();
  95. }
  96. }
  97. if (opt.index < argc)
  98. f = argv[opt.index++];
  99. if (opt.index < argc)
  100. g = argv[opt.index++];
  101. if (!f)
  102. FAIL("no function specified");
  103. else if (opt.index < argc)
  104. FAIL("too many arguments");
  105. if (real(xmin.C()) >= real(xmax.C()))
  106. FAIL("invalid range");
  107. remez_solver solver(degree, 20);
  108. solver.run(xmin.C(), xmax.C(), f, g);
  109. return 0;
  110. }