PageRenderTime 28ms CodeModel.GetById 11ms RepoModel.GetById 1ms app.codeStats 0ms

/libmatheval-1.1.8/tests/matheval.c

#
C | 366 lines | 269 code | 41 blank | 56 comment | 22 complexity | 004b75f661a2170e8490b5fdab3a58c9 MD5 | raw file
Possible License(s): GPL-3.0
  1. /*
  2. * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2011 Free
  3. * Software Foundation, Inc.
  4. *
  5. * This file is part of GNU libmatheval
  6. *
  7. * GNU libmatheval is free software: you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License as
  9. * published by the Free Software Foundation, either version 3 of the
  10. * License, or (at your option) any later version.
  11. *
  12. * GNU libmatheval is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with GNU libmatheval. If not, see
  19. * <http://www.gnu.org/licenses/>.
  20. */
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include <assert.h>
  24. #include <libguile.h>
  25. #include <matheval.h>
  26. #include "config.h"
  27. #ifndef HAVE_SCM_T_BITS
  28. typedef long scm_t_bits;
  29. #endif
  30. #ifndef HAVE_SCM_NUM2DBL
  31. #ifdef SCM_NUM2DBL
  32. #define scm_num2dbl(x,s) SCM_NUM2DBL(x)
  33. #else
  34. #error Neither scm_num2dbl() nor SCM_NUM2DBL available
  35. #endif
  36. #endif
  37. #ifndef HAVE_SCM_C_DEFINE_GSUBR
  38. #ifdef HAVE_SCM_MAKE_GSUBR
  39. #define scm_c_define_gsubr scm_make_gsubr
  40. #else
  41. #error Neither scm_c_define_gsubr() nor scm_make_gsubr() available
  42. #endif
  43. #endif
  44. static scm_t_bits evaluator_tag; /* Unique identifier for Guile
  45. * objects of evaluator type. */
  46. /* Guile interface for libmatheval library. Procedures below are simple
  47. * wrappers for corresponding libmatheval procedures. */
  48. static scm_sizet evaluator_destroy_scm(SCM evaluator_smob);
  49. static SCM evaluator_create_scm(SCM string);
  50. static SCM evaluator_evaluate_scm(SCM evaluator_smob, SCM count,
  51. SCM names, SCM values);
  52. static SCM evaluator_get_string_scm(SCM evaluator_smob);
  53. static SCM evaluator_get_variables_scm(SCM evaluator_smob);
  54. static SCM evaluator_derivative_scm(SCM evaluator_smob, SCM name);
  55. static SCM evaluator_evaluate_x_scm(SCM evaluator_smob, SCM x);
  56. static SCM evaluator_evaluate_x_y_scm(SCM evaluator_smob, SCM x,
  57. SCM y);
  58. static SCM evaluator_evaluate_x_y_z_scm(SCM evaluator_smob, SCM x,
  59. SCM y, SCM z);
  60. static SCM evaluator_derivative_x_scm(SCM evaluator_smob);
  61. static SCM evaluator_derivative_y_scm(SCM evaluator_smob);
  62. static SCM evaluator_derivative_z_scm(SCM evaluator_smob);
  63. static void
  64. inner_main(void *closure, int argc, char **argv)
  65. {
  66. /* Extend Guile with evaluator type and register procedure to free
  67. * objects of this type. */
  68. evaluator_tag = scm_make_smob_type("evaluator", sizeof(void *));
  69. scm_set_smob_free(evaluator_tag, evaluator_destroy_scm);
  70. /* Register other procedures working on evaluator type. */
  71. scm_c_define_gsubr("evaluator-create", 1, 0, 0,
  72. (SCM(*)())evaluator_create_scm);
  73. scm_c_define_gsubr("evaluator-evaluate", 4, 0, 0,
  74. (SCM(*)())evaluator_evaluate_scm);
  75. scm_c_define_gsubr("evaluator-get-string", 1, 0, 0,
  76. (SCM(*)())evaluator_get_string_scm);
  77. scm_c_define_gsubr("evaluator-get-variables", 1, 0, 0,
  78. (SCM(*)())evaluator_get_variables_scm);
  79. scm_c_define_gsubr("evaluator-derivative", 2, 0, 0,
  80. (SCM(*)())evaluator_derivative_scm);
  81. scm_c_define_gsubr("evaluator-evaluate-x", 2, 0, 0,
  82. (SCM(*)())evaluator_evaluate_x_scm);
  83. scm_c_define_gsubr("evaluator-evaluate-x-y", 3, 0, 0,
  84. (SCM(*)())evaluator_evaluate_x_y_scm);
  85. scm_c_define_gsubr("evaluator-evaluate-x-y-z", 4, 0, 0,
  86. (SCM(*)())evaluator_evaluate_x_y_z_scm);
  87. scm_c_define_gsubr("evaluator-derivative-x", 1, 0, 0,
  88. (SCM(*)())evaluator_derivative_x_scm);
  89. scm_c_define_gsubr("evaluator-derivative-y", 1, 0, 0,
  90. (SCM(*)())evaluator_derivative_y_scm);
  91. scm_c_define_gsubr("evaluator-derivative-z", 1, 0, 0,
  92. (SCM(*)())evaluator_derivative_z_scm);
  93. /* Check is there exactly one argument left in command line. */
  94. assert(argc == 2);
  95. /* Interpret Guile code from file with name given through above
  96. * argument. */
  97. scm_primitive_load(scm_makfrom0str(argv[1]));
  98. }
  99. /* Program is demonstrating use of libmatheval library of procedures for
  100. * evaluating mathematical functions. Program expects single argument
  101. * from command line and interpret Guile code (extended with procedures
  102. * from libmatheval Guile interface) from this file. */
  103. int
  104. main(int argc, char **argv)
  105. {
  106. /* Initialize Guile library; inner_main() procedure gets called in
  107. * turn. */
  108. scm_boot_guile(argc, argv, inner_main, 0);
  109. exit(EXIT_SUCCESS);
  110. }
  111. /* Wrapper for evaluator_destroy() procedure from libmatheval library. */
  112. static scm_sizet
  113. evaluator_destroy_scm(SCM evaluator_smob)
  114. {
  115. SCM_ASSERT((SCM_NIMP(evaluator_smob)
  116. && SCM_SMOB_PREDICATE(evaluator_tag, evaluator_smob)),
  117. evaluator_smob, SCM_ARG1, "evaluator-destroy");
  118. evaluator_destroy((void *) SCM_CDR(evaluator_smob));
  119. return sizeof(void *);
  120. }
  121. /* Wrapper for evaluator_create() procedure from libmatheval library. */
  122. static SCM
  123. evaluator_create_scm(SCM string)
  124. {
  125. char *stringz;
  126. void *evaluator;
  127. SCM_ASSERT(SCM_NIMP(string)
  128. && SCM_STRINGP(string), string, SCM_ARG1,
  129. "evaluator-create");
  130. stringz = (char *) malloc((SCM_LENGTH(string) + 1) * sizeof(char));
  131. memcpy(stringz, SCM_CHARS(string), SCM_LENGTH(string));
  132. stringz[SCM_LENGTH(string)] = 0;
  133. evaluator = evaluator_create(stringz);
  134. free(stringz);
  135. SCM_RETURN_NEWSMOB(evaluator_tag, evaluator);
  136. }
  137. /* Wrapper for evaluator_evaluate() procedure from libmatheval library.
  138. * Variable names and values are passed as lists from Guile, so copies of
  139. * these argument have to be created in order to be able to call
  140. * evaluator_evaluate() procedure. */
  141. static SCM
  142. evaluator_evaluate_scm(SCM evaluator_smob, SCM count, SCM names,
  143. SCM values)
  144. {
  145. SCM name;
  146. char **names_copy;
  147. SCM value;
  148. double *values_copy;
  149. double result;
  150. int i;
  151. SCM_ASSERT((SCM_NIMP(evaluator_smob)
  152. && SCM_SMOB_PREDICATE(evaluator_tag, evaluator_smob)),
  153. evaluator_smob, SCM_ARG1, "evaluator-evaluate");
  154. SCM_ASSERT(SCM_INUMP(count), count, SCM_ARG2,
  155. "evaluator-evaluate");
  156. names_copy = (char **) malloc(SCM_INUM(count) * sizeof(char *));
  157. for (i = 0, name = names; i < SCM_INUM(count);
  158. i++, name = SCM_CDR(name)) {
  159. SCM_ASSERT(SCM_NIMP(name) && SCM_CONSP(name)
  160. && SCM_STRINGP(SCM_CAR(name)), names, SCM_ARG3,
  161. "evaluator-evaluate");
  162. names_copy[i] =
  163. (char *) malloc((SCM_LENGTH(SCM_CAR(name)) + 1) *
  164. sizeof(char));
  165. memcpy(names_copy[i], SCM_CHARS(SCM_CAR(name)),
  166. SCM_LENGTH(SCM_CAR(name)));
  167. names_copy[i][SCM_LENGTH(SCM_CAR(name))] = 0;
  168. }
  169. values_copy = (double *) malloc(SCM_INUM(count) * sizeof(double));
  170. for (i = 0, value = values; i < SCM_INUM(count);
  171. i++, value = SCM_CDR(value)) {
  172. SCM_ASSERT(SCM_NIMP(value) && SCM_CONSP(value)
  173. && SCM_NUMBERP(SCM_CAR(value)), values,
  174. SCM_ARG4, "evaluator-evaluate");
  175. values_copy[i] =
  176. scm_num2dbl(SCM_CAR(value), "evaluator-evaluate");
  177. }
  178. result =
  179. evaluator_evaluate((void *) SCM_CDR(evaluator_smob),
  180. SCM_INUM(count), names_copy, values_copy);
  181. for (i = 0; i < SCM_INUM(count); i++)
  182. free(names_copy[i]);
  183. free(names_copy);
  184. free(values_copy);
  185. return scm_make_real(result);
  186. }
  187. /* Wrapper for evaluator_get_string() procedure from libmatheval library. */
  188. static SCM
  189. evaluator_get_string_scm(SCM evaluator_smob)
  190. {
  191. SCM_ASSERT((SCM_NIMP(evaluator_smob)
  192. && SCM_SMOB_PREDICATE(evaluator_tag, evaluator_smob)),
  193. evaluator_smob, SCM_ARG1, "evaluator-get-string");
  194. return
  195. scm_makfrom0str(evaluator_get_string
  196. ((void *) SCM_CDR(evaluator_smob)));
  197. }
  198. /* Wrapper for evaluator_get_variables() procedure from libmatheval
  199. * library. */
  200. static SCM
  201. evaluator_get_variables_scm(SCM evaluator_smob)
  202. {
  203. char **names;
  204. int count;
  205. SCM list;
  206. int i;
  207. SCM_ASSERT((SCM_NIMP(evaluator_smob)
  208. && SCM_SMOB_PREDICATE(evaluator_tag, evaluator_smob)),
  209. evaluator_smob, SCM_ARG1, "evaluator-get-string");
  210. evaluator_get_variables((void *) SCM_CDR(evaluator_smob), &names,
  211. &count);
  212. list = SCM_EOL;
  213. for (i = 0; i < count; i++)
  214. list =
  215. scm_append_x(scm_listify
  216. (list,
  217. scm_listify(scm_makfrom0str(names[i]),
  218. SCM_UNDEFINED),
  219. SCM_UNDEFINED));
  220. return list;
  221. }
  222. /* Wrapper for evaluator_derivative() procedure from libmatheval library. */
  223. static SCM
  224. evaluator_derivative_scm(SCM evaluator_smob, SCM name)
  225. {
  226. SCM_ASSERT((SCM_NIMP(evaluator_smob)
  227. && SCM_SMOB_PREDICATE(evaluator_tag, evaluator_smob)),
  228. evaluator_smob, SCM_ARG1, "evaluator-derivative");
  229. SCM_ASSERT(SCM_NIMP(name)
  230. && SCM_STRINGP(name), name, SCM_ARG2,
  231. "evaluator-derivative");
  232. SCM_RETURN_NEWSMOB(evaluator_tag,
  233. evaluator_derivative((void *)
  234. SCM_CDR(evaluator_smob),
  235. SCM_CHARS(name)));
  236. }
  237. /* Wrapper for evaluator_evaluate_x() procedure from libmatheval library. */
  238. static SCM
  239. evaluator_evaluate_x_scm(SCM evaluator_smob, SCM x)
  240. {
  241. SCM_ASSERT((SCM_NIMP(evaluator_smob)
  242. && SCM_SMOB_PREDICATE(evaluator_tag, evaluator_smob)),
  243. evaluator_smob, SCM_ARG1, "evaluator-evaluate-x");
  244. SCM_ASSERT(SCM_NUMBERP(x), x, SCM_ARG2, "evaluator-evaluate-x");
  245. return
  246. scm_make_real(evaluator_evaluate_x
  247. ((void *) SCM_CDR(evaluator_smob),
  248. scm_num2dbl(x, "evaluator-evaluate-x")));
  249. }
  250. /* Wrapper for evaluator_evaluate_x_y() procedure from libmatheval
  251. * library. */
  252. static SCM
  253. evaluator_evaluate_x_y_scm(SCM evaluator_smob, SCM x, SCM y)
  254. {
  255. SCM_ASSERT((SCM_NIMP(evaluator_smob)
  256. && SCM_SMOB_PREDICATE(evaluator_tag, evaluator_smob)),
  257. evaluator_smob, SCM_ARG1, "evaluator-evaluate-x-y");
  258. SCM_ASSERT(SCM_NUMBERP(x), x, SCM_ARG2, "evaluator-evaluate-x-y");
  259. SCM_ASSERT(SCM_NUMBERP(y), y, SCM_ARG3, "evaluator-evaluate-x-y");
  260. return
  261. scm_make_real(evaluator_evaluate_x_y
  262. ((void *) SCM_CDR(evaluator_smob),
  263. scm_num2dbl(x, "evaluator-evaluate-x-y"),
  264. scm_num2dbl(y, "evaluator-evaluate-x-y")));
  265. }
  266. /* Wrapper for evaluator_evaluate_x_y_z() procedure from libmatheval
  267. * library. */
  268. static SCM
  269. evaluator_evaluate_x_y_z_scm(SCM evaluator_smob, SCM x, SCM y, SCM z)
  270. {
  271. SCM_ASSERT((SCM_NIMP(evaluator_smob)
  272. && SCM_SMOB_PREDICATE(evaluator_tag, evaluator_smob)),
  273. evaluator_smob, SCM_ARG1, "evaluator-evaluate-x-y-z");
  274. SCM_ASSERT(SCM_NUMBERP(x), x, SCM_ARG2,
  275. "evaluator-evaluate-x-y-z");
  276. SCM_ASSERT(SCM_NUMBERP(y), y, SCM_ARG3,
  277. "evaluator-evaluate-x-y-z");
  278. SCM_ASSERT(SCM_NUMBERP(z), z, SCM_ARG4,
  279. "evaluator-evaluate-x-y-z");
  280. return
  281. scm_make_real(evaluator_evaluate_x_y_z
  282. ((void *) SCM_CDR(evaluator_smob),
  283. scm_num2dbl(x, "evaluator-evaluate-x-y-z"),
  284. scm_num2dbl(y, "evaluator-evaluate-x-y-z"),
  285. scm_num2dbl(z, "evaluator-evaluate-x-y-z")));
  286. }
  287. /* Wrapper for evaluator_derivative_x() procedure from libmatheval
  288. * library. */
  289. static SCM
  290. evaluator_derivative_x_scm(SCM evaluator_smob)
  291. {
  292. SCM_ASSERT((SCM_NIMP(evaluator_smob)
  293. && SCM_SMOB_PREDICATE(evaluator_tag, evaluator_smob)),
  294. evaluator_smob, SCM_ARG1, "evaluator-derivative-x");
  295. SCM_RETURN_NEWSMOB(evaluator_tag,
  296. evaluator_derivative((void *)
  297. SCM_CDR(evaluator_smob),
  298. "x"));
  299. }
  300. /* Wrapper for evaluator_derivative_y() procedure from libmatheval
  301. * library. */
  302. static SCM
  303. evaluator_derivative_y_scm(SCM evaluator_smob)
  304. {
  305. SCM_ASSERT((SCM_NIMP(evaluator_smob)
  306. && SCM_SMOB_PREDICATE(evaluator_tag, evaluator_smob)),
  307. evaluator_smob, SCM_ARG1, "evaluator-derivative-y");
  308. SCM_RETURN_NEWSMOB(evaluator_tag,
  309. evaluator_derivative((void *)
  310. SCM_CDR(evaluator_smob),
  311. "y"));
  312. }
  313. /* Wrapper for evaluator_derivative_z() procedure from libmatheval
  314. * library. */
  315. static SCM
  316. evaluator_derivative_z_scm(SCM evaluator_smob)
  317. {
  318. SCM_ASSERT((SCM_NIMP(evaluator_smob)
  319. && SCM_SMOB_PREDICATE(evaluator_tag, evaluator_smob)),
  320. evaluator_smob, SCM_ARG1, "evaluator-derivative-z");
  321. SCM_RETURN_NEWSMOB(evaluator_tag,
  322. evaluator_derivative((void *)
  323. SCM_CDR(evaluator_smob),
  324. "z"));
  325. }