Add prelimiary check_* code for each *.h file in sawsim.nw.
authorW. Trevor King <wking@drexel.edu>
Mon, 18 Oct 2010 19:50:23 +0000 (15:50 -0400)
committerW. Trevor King <wking@drexel.edu>
Mon, 18 Oct 2010 19:50:23 +0000 (15:50 -0400)
src/sawsim.nw

index 9e666be3106877111d04b7bc2e9f2913c1cc62f3..3f810b737a93db64af2cc9aea1ff697f1419c2c4 100644 (file)
@@ -742,6 +742,7 @@ and unfolding models are defined in Appendix \ref{sec.k_models}.
 
 <<model globals>>=
 #define k_B   1.3806503e-23  /* J/K */
+
 @
 
 
@@ -1259,6 +1260,7 @@ We include [[math.h]], so don't forget to link to the libm with `-lm'.
 #include "tension_model.h"
 #include "parse.h"
 #include "accel_k.h"
+
 @
 
 <<definitions>>=
@@ -1343,6 +1345,7 @@ We also define a macro for our [[check]] unit testing
                 -(received-expected)/expected, max_err, #received,           \
                  expected, received);                                        \
   } while(0)
+
 @
 
 <<happens>>=
@@ -2049,6 +2052,7 @@ void free_parsed_list(int num, char **string_array)
 
 Here we check to make sure the various functions work as expected, using \citetalias{sw:check}.
 <<check-parse.c>>=
+<<license comment>>
 <<parse check includes>>
 <<string comparison definition and globals>>
 <<check relative error>>
@@ -2073,10 +2077,10 @@ Here we check to make sure the various functions work as expected, using \citeta
 <<parse suite definition>>=
 Suite *test_suite (void)
 {
-  Suite *s = suite_create ("k model");
+  Suite *s = suite_create ("parse");
   <<parse list string test case defs>>
 
-  <<parse list string test case add>>
+  <<parse list string test case adds>>
   return s;
 }
 @
@@ -2150,7 +2154,7 @@ END_TEST
 <<parse list string test case defs>>=
 TCase *tc_parse_list_string = tcase_create("parse list string");
 @
-<<parse list string test case add>>=
+<<parse list string test case adds>>=
 //tcase_add_test(tc_parse_list_string, test_next_delim_index);
 tcase_add_test(tc_parse_list_string, test_parse_list_null);
 tcase_add_test(tc_parse_list_string, test_parse_list_single_simple);
@@ -2184,7 +2188,6 @@ Here we check to make sure the various functions work as expected, using \citeta
 @
 
 <<test suite>>=
-<<F tests>>
 <<determine dt tests>>
 <<happens tests>>
 <<does domain transition tests>>
@@ -2196,17 +2199,15 @@ Here we check to make sure the various functions work as expected, using \citeta
 Suite *test_suite (void)
 {
   Suite *s = suite_create ("sawsim");
-  <<F test case defs>>
   <<determine dt test case defs>>
   <<happens test case defs>>
   <<does domain transition test case defs>>
   <<randomly unfold domains test case defs>>
 
-  <<F test case add>>
-  <<determine dt test case add>>
-  <<happens test case add>>
-  <<does domain transition test case add>>
-  <<randomly unfold domains test case add>>
+  <<determine dt test case adds>>
+  <<happens test case adds>>
+  <<does domain transition test case adds>>
+  <<randomly unfold domains test case adds>>
 
 /*
   tcase_add_checked_fixture(tc_strip_address,
@@ -2230,54 +2231,6 @@ int main(void)
 }
 @
 
-\subsection{F tests}
-<<F tests>>=
-<<worm-like chain tests>>
-@
-<<F test case defs>>=
-<<worm-like chain test case def>>
-@
-<<F test case add>>=
-<<worm-like chain test case add>>
-@
-
-<<worm-like chain tests>>=
-<<worm-like chain function>>
-
-START_TEST(test_wlc_at_zero)
-{
-  double T=1.0, L=1.0, p=0.1, x=0.0, lim=1e-30;
-  fail_unless(abs(wlc(x, T, p, L)) < lim, \
-              "abs(wlc(x=%g,T=%g,p=%g,L=%g)) = %g >= %g",
-              x, T, p, L, abs(wlc(x, T, p, L)), lim);
-}
-END_TEST
-
-START_TEST(test_wlc_at_half)
-{
-  double T=1.0, L=1.0, p=0.1*k_B, x=0.5;
-  /* prefactor = k_B T / p = k_B 1.0 / (k_B*0.1) = 10.0 J/nm = 10.0e21 pN
-   * nonlinear term = 0.25 (1/(1-x/L)^2-1) = 0.25(1/.25 - 1)
-   *                = 0.25 * 3 = 3/4
-   * linear term = x/L = 0.5
-   * nonlinear + linear = 0.75 + 0.5 = 1.25
-   * wlc = 10e21*1.25 = 12.5e21
-   */
-  fail_unless(wlc(x, T, p, L)-12.5e21 < 1e16,
-              "wlc(%g, %g, %g, %g) = %g != %g",
-               x, T, p, L, wlc(x, T, p, L), 12.5e21);
-}
-END_TEST
-@
-<<worm-like chain test case def>>=
-TCase *tc_wlc = tcase_create("WLC");
-@
-
-<<worm-like chain test case add>>=
-tcase_add_test(tc_wlc, test_wlc_at_zero);
-tcase_add_test(tc_wlc, test_wlc_at_half);
-suite_add_tcase(s, tc_wlc);
-@
 
 \subsection{Model tests}
 
@@ -2318,7 +2271,7 @@ END_TEST
 <<determine dt test case defs>>=
 TCase *tc_determine_dt = tcase_create("Determine dt");
 @
-<<determine dt test case add>>=
+<<determine dt test case adds>>=
 tcase_add_test(tc_determine_dt, test_determine_dt_linear_k);
 suite_add_tcase(s, tc_determine_dt);
 @
@@ -2327,21 +2280,21 @@ suite_add_tcase(s, tc_determine_dt);
 @
 <<happens test case defs>>=
 @
-<<happens test case add>>=
+<<happens test case adds>>=
 @
 
 <<does domain transition tests>>=
 @
 <<does domain transition test case defs>>=
 @
-<<does domain transition test case add>>=
+<<does domain transition test case adds>>=
 @
 
 <<randomly unfold domains tests>>=
 @
 <<randomly unfold domains test case defs>>=
 @
-<<randomly unfold domains test case add>>=
+<<randomly unfold domains test case adds>>=
 @
 
 
@@ -2810,6 +2763,7 @@ double length_scale = 1e-10; /* HACK */
 
 Here we check to make sure the various functions work as expected, using \citetalias{sw:check}.
 <<check-tension-balance.c>>=
+<<license comment>>
 <<tension balance check includes>>
 <<tension balance test suite>>
 <<main check program>>
@@ -3316,6 +3270,7 @@ The user must free the data pointed to by the node on their own.
 
 Here we check to make sure the various functions work as expected, using \citetalias{sw:check}.
 <<check-list.c>>=
+<<license comment>>
 <<list check includes>>
 <<list test suite>>
 <<main check program>>
@@ -3613,6 +3568,7 @@ The [[while]] loop around [[wait]] protects [[wait]] from interrupting signals.
 
 Here we check to make sure the various functions work as expected, using \citetalias{sw:check}.
 <<check-string-eval.c>>=
+<<license comment>>
 <<string eval check includes>>
 <<string comparison definition and globals>>
 <<string eval test suite>>
@@ -3640,7 +3596,7 @@ Suite *test_suite (void)
   Suite *s = suite_create ("string eval");
   <<string eval test case defs>>
 
-  <<string eval test case add>>
+  <<string eval test case adds>>
   return s;
 }
 @
@@ -3658,7 +3614,7 @@ START_TEST(test_invalid_command)
   FILE *in, *out;
   char input[80], output[80]={};
   string_eval_setup(&in, &out);
-  sprintf(input, "print ABCDefg\n");
+  sprintf(input, "print undefined_name__traceback_should_be_printed_to_stderr\n");
   string_eval(in, out, input, 80, output);
   string_eval_teardown(&in, &out);
 }
@@ -3705,7 +3661,7 @@ END_TEST
 <<string eval test case defs>>=
 TCase *tc_string_eval = tcase_create("string_eval");
 @
-<<string eval test case add>>=
+<<string eval test case adds>>=
 tcase_add_test(tc_string_eval, test_setup_teardown);
 tcase_add_test_raise_signal(tc_string_eval, test_invalid_command, SIGKILL);
 tcase_add_test(tc_string_eval, test_simple_eval);
@@ -3728,6 +3684,7 @@ The number of evaluation calls could be drastically reduced, however, by impleme
 <<accel-k.h>>=
 #ifndef ACCEL_K_H
 #define ACCEL_K_H
+<<license comment>>
 double accel_k(k_func_t *k, double F, environment_t *env, void *params);
 void free_accels();
 #endif /* ACCEL_K_H */
@@ -3735,11 +3692,12 @@ void free_accels();
 
 <<accel k module makefile lines>>=
 NW_SAWSIM_MODS += accel_k
-#CHECK_BINS += check_accel_k
-check_accel_k_MODS =
+CHECK_BINS += check_accel_k
+check_accel_k_MODS = interp k_model parse string_eval tavl
 @
 
 <<accel-k.c>>=
+<<license comment>>
 #include <assert.h>  /* assert()                */
 #include <stdlib.h>  /* realloc(), free(), NULL */
 #include "global.h"  /* environment_t           */
@@ -3815,6 +3773,77 @@ double accel_k(k_func_t *k, double F, environment_t *env, void *params)
 }
 @
 
+\subsection{Unit tests}
+
+Here we check to make sure the various functions work as expected, using \citetalias{sw:check}.
+<<check-accel-k.c>>=
+<<license comment>>
+<<accel k check includes>>
+<<check relative error>>
+<<model globals>>
+<<accel k test suite>>
+<<main check program>>
+@
+
+<<accel k check includes>>=
+#include <stdlib.h> /* EXIT_SUCCESS, EXIT_FAILURE */
+#include <stdio.h>  /* sprintf()                  */
+#include <assert.h> /* assert()                   */
+#include <math.h>   /* exp()                      */
+#include <errno.h>  /* errno, ERANGE              */
+<<check includes>>
+#include "global.h"
+#include "k_model.h"
+#include "accel_k.h"
+
+@
+
+<<accel k test suite>>=
+<<accel k suite tests>>
+<<accel k suite definition>>
+@
+
+<<accel k suite definition>>=
+Suite *test_suite (void)
+{
+  Suite *s = suite_create ("accelerated k model");
+  <<accel k test case defs>>
+
+  <<accel k test case adds>>
+  return s;
+}
+@
+
+<<accel k test case defs>>=
+TCase *tc_accel_k = tcase_create("accelerated k model");
+@
+
+<<accel k test case adds>>=
+tcase_add_test(tc_accel_k, test_accel_k_accuracy);
+suite_add_tcase(s, tc_accel_k);
+@
+
+<<accel k suite tests>>=
+START_TEST(test_accel_k_accuracy)
+{
+  double k, k_accel, F, Fm=0.0, FM=300e-12, dF=0.5e-12;
+  k_func_t *k_func = bell_k;
+  char *param_strings[] = {"3.3e-4", "0.25e-9"};
+  void *params = string_create_bell_param_t(param_strings);
+  environment_t env = {};
+  env.T = 300.0;
+
+  for(F=Fm; F <= FM; F+=dF) {
+    k = k_func(F, &env, params);
+    k_accel = accel_k(k_func, F, &env, params);
+    CHECK_ERR(1e-8, k, k_accel);
+  }
+  destroy_bell_param_t(params);
+}
+END_TEST
+
+@
+
 \section{Tension models}
 \label{sec.tension_models}
 
@@ -3841,8 +3870,8 @@ The interface is defined in [[tension_model.h]], the implementation in [[tension
 
 <<tension model module makefile lines>>=
 NW_SAWSIM_MODS += tension_model
-#CHECK_BINS += check_tension_model
-check_tension_model_MODS =
+CHECK_BINS += check_tension_model
+check_tension_model_MODS = list tension_balance
 @
 <<tension model utils makefile lines>>=
 TENSION_MODEL_MODS = tension_model parse list tension_balance
@@ -4381,14 +4410,13 @@ $$
 $$
 where $L=Nl$ is the total length of the chain, and $\mathcal{L}(\alpha) \equiv \coth{\alpha} - \frac{1}{\alpha}$ is the Langevin function\citep{hatfield99}.
 <<freely-jointed chain function>>=
-double langevin(double x, void *params)
+static double langevin(double x, void *params)
 {
   if (x==0) return 0;
   return 1.0/tanh(x) - 1/x;
 }
-<<one dimensional bracket declaration>>
-<<one dimensional solve declaration>>
-double inv_langevin(double x)
+
+static double inv_langevin(double x)
 {
   double lb=0.0, ub=1.0, ret;
   oneD_bracket(&langevin, NULL, x, 1.0, &lb, &ub);
@@ -4396,13 +4424,14 @@ double inv_langevin(double x)
   return ret;
 }
 
-double fjc(double x, double T, double l, int N)
+static double fjc(double x, double T, double l, int N)
 {
   double L = l*(double)N;
   if (x == 0) return 0;
   //printf("x %g\tL%g\tx/L %g\n", x, L, x/L);
   return k_B*T/l * inv_langevin(x/L);
 }
+
 @
 
 <<freely-jointed chain handler declaration>>=
@@ -4896,6 +4925,239 @@ void get_options(int argc, char **argv, environment_t *env,
 }
 @
 
+\subsection{Tension model unit tests}
+
+Here we check to make sure the various functions work as expected, using \citetalias{sw:check}.
+<<check-tension-model.c>>=
+<<license comment>>
+<<tension model check includes>>
+<<check relative error>>
+<<model globals>>
+<<tension model test suite>>
+<<main check program>>
+@
+
+<<tension model check includes>>=
+#include <stdlib.h> /* EXIT_SUCCESS, EXIT_FAILURE */
+#include <stdio.h>  /* sprintf()                  */
+#include <assert.h> /* assert()                   */
+#include <math.h>   /* exp()                      */
+#include <errno.h>  /* errno, ERANGE              */
+<<check includes>>
+#include "global.h"
+#include "list.h"
+#include "tension_balance.h" /* oneD_*() */
+#include "tension_model.h"
+@
+
+<<tension model test suite>>=
+<<safe strto*>>
+<<const tension tests>>
+<<hooke tests>>
+<<worm-like chain tests>>
+<<freely-jointed chain tests>>
+<<piston tests>>
+<<tension model suite definition>>
+@
+
+<<tension model suite definition>>=
+Suite *test_suite (void)
+{
+  Suite *s = suite_create ("tension model");
+  <<const tension test case defs>>
+  <<hooke test case defs>>
+  <<worm-like chain test case defs>>
+  <<freely-jointed chain test case defs>>
+  <<piston test case defs>>
+
+  <<const tension test case adds>>
+  <<hooke test case adds>>
+  <<worm-like chain test case adds>>
+  <<freely-jointed chain test case adds>>
+  <<piston test case adds>>
+  return s;
+}
+@
+
+\subsubsection{Constant}
+
+<<const tension test case defs>>=
+TCase *tc_const_tension = tcase_create("Constant tension");
+@
+
+<<const tension test case adds>>=
+tcase_add_test(tc_const_tension, test_const_tension_create_destroy);
+suite_add_tcase(s, tc_const_tension);
+@
+
+<<const tension tests>>=
+START_TEST(test_const_tension_create_destroy)
+{
+  char *tension[] = {"1","2.2", "3"};
+  char *params[] = {tension[0]};
+  void *p = NULL;
+  int i;
+  for( i=0; i < sizeof(tension)/sizeof(char *); i++) {
+    params[0] = tension[i];
+    p = string_create_const_tension_param_t(params);
+    destroy_const_tension_param_t(p);
+  }
+}
+END_TEST
+
+@ TODO: In order to test the constant tension handler itself, we'd
+have to construct a group.
+
+
+\subsubsection{Hooke}
+
+<<hooke test case defs>>=
+TCase *tc_hooke = tcase_create("Hooke");
+@
+
+<<hooke test case adds>>=
+tcase_add_test(tc_hooke, test_hooke_create_destroy);
+suite_add_tcase(s, tc_hooke);
+
+@
+
+<<hooke tests>>=
+START_TEST(test_hooke_create_destroy)
+{
+  char *k[] = {"1","2.2", "3"};
+  char *params[] = {k[0]};
+  void *p = NULL;
+  int i;
+  for( i=0; i < sizeof(k)/sizeof(char *); i++) {
+    params[0] = k[i];
+    p = string_create_hooke_param_t(params);
+    destroy_hooke_param_t(p);
+  }
+}
+END_TEST
+
+@ TODO: In order to test the Hooke tension handler itself, we'd
+have to construct a group.
+
+
+\subsubsection{Worm-like chain}
+
+<<worm-like chain test case defs>>=
+TCase *tc_wlc = tcase_create("WLC");
+@
+
+<<worm-like chain test case adds>>=
+tcase_add_test(tc_wlc, test_wlc_at_zero);
+tcase_add_test(tc_wlc, test_wlc_at_half);
+suite_add_tcase(s, tc_wlc);
+
+@
+
+<<worm-like chain tests>>=
+<<worm-like chain function>>
+START_TEST(test_wlc_at_zero)
+{
+  double T=1.0, L=1.0, p=0.1, x=0.0, lim=1e-30;
+  fail_unless(abs(wlc(x, T, p, L)) < lim, \
+              "abs(wlc(x=%g,T=%g,p=%g,L=%g)) = %g >= %g",
+              x, T, p, L, abs(wlc(x, T, p, L)), lim);
+}
+END_TEST
+
+START_TEST(test_wlc_at_half)
+{
+  double T=1.0, L=1.0, p=0.1*k_B, x=0.5;
+  /* prefactor = k_B T / p = k_B 1.0 / (k_B*0.1) = 10.0 J/nm = 10.0e21 pN
+   * nonlinear term = 0.25 (1/(1-x/L)^2-1) = 0.25(1/.25 - 1)
+   *                = 0.25 * 3 = 3/4
+   * linear term = x/L = 0.5
+   * nonlinear + linear = 0.75 + 0.5 = 1.25
+   * wlc = 10e21*1.25 = 12.5e21
+   */
+  fail_unless(wlc(x, T, p, L)-12.5e21 < 1e16,
+              "wlc(%g, %g, %g, %g) = %g != %g",
+               x, T, p, L, wlc(x, T, p, L), 12.5e21);
+}
+END_TEST
+
+@
+
+
+\subsubsection{Freely-jointed chain}
+
+<<freely-jointed chain test case defs>>=
+TCase *tc_fjc = tcase_create("FJC");
+@
+
+<<freely-jointed chain test case adds>>=
+tcase_add_test(tc_fjc, test_fjc_at_zero);
+tcase_add_test(tc_fjc, test_fjc_at_half);
+suite_add_tcase(s, tc_fjc);
+
+@
+
+<<freely-jointed chain tests>>=
+<<freely-jointed chain function>>
+START_TEST(test_fjc_at_zero)
+{
+  int N=10;
+  double T=1.0, l=1.0, p=0.1, x=0.0, lim=1e-30;
+  fail_unless(abs(fjc(x, T, l, N)) < lim, \
+              "abs(fjc(x=%g,T=%g,l=%g,N=%d)) = %g >= %g",
+              x, T, l, N, abs(fjc(x, T, l, N)), lim);
+}
+END_TEST
+
+START_TEST(test_fjc_at_half)
+{
+  int N = 10;
+  double T=1.0/k_B, l=1.0, x=5.0;
+  /* prefactor = k_B T / l = k_B (1.0/k_B) / 1.0 = 1.0 J/nm = 1.0e21 pN
+   * nonlinear term = 0.25 (1/(1-x/L)^2-1) = 0.25(1/.25 - 1)
+   *                = 0.25 * 3 = 3/4
+   * linear term = x/L = 0.5
+   * nonlinear + linear = 0.75 + 0.5 = 1.25
+   * fjc = 10e21*1.25 = 12.5e21
+   */
+  fail_unless(fjc(x, T, l, N)-12.5e21 < 1e16,
+              "fjc(%g, %g, %g, %d) = %g != %g",
+               x, T, l, N, fjc(x, T, l, N), 12.5e21);
+}
+END_TEST
+
+@
+
+
+\subsubsection{Piston}
+
+<<piston test case defs>>=
+TCase *tc_piston = tcase_create("Piston");
+@
+
+<<piston test case adds>>=
+tcase_add_test(tc_piston, test_piston_create_destroy);
+suite_add_tcase(s, tc_piston);
+
+@
+
+<<piston tests>>=
+START_TEST(test_piston_create_destroy)
+{
+  char *L[] = {"1","2.2", "3"};
+  char *params[] = {L[0]};
+  void *p = NULL;
+  int i;
+  for( i=0; i < sizeof(L)/sizeof(char *); i++) {
+    params[0] = L[i];
+    p = string_create_piston_tension_param_t(params);
+    destroy_piston_tension_param_t(p);
+  }
+}
+END_TEST
+
+@ TODO: In order to test the piston tension handler itself, we'd
+have to construct a group.
+
 
 \section{Unfolding rate models}
 \label{sec.k_models}
@@ -5824,6 +6086,7 @@ Initialized with Titin I27 parameters\citep{carrion-vazquez99a}.
 
 Here we check to make sure the various functions work as expected, using \citetalias{sw:check}.
 <<check-k-model.c>>=
+<<license comment>>
 <<k model check includes>>
 <<check relative error>>
 <<model globals>>
@@ -5993,10 +6256,10 @@ END_TEST
 <<kramers k tests>>=
 @
 
-<<kramers k test case def>>=
+<<kramers k test case defs>>=
 @
 
-<<kramers k test case add>>=
+<<kramers k test case adds>>=
 @
 
 <<k model function tests>>=
@@ -6314,6 +6577,7 @@ DOC_DIR = doc
 
 # Modules (X.c, X.h) defined in the noweb file
 NW_SAWSIM_MODS =
+# Check binaries (check_*) defined in the noweb file
 CHECK_BINS =
 # Modules defined outside the noweb file
 FREE_SAWSIM_MODS = interp tavl
@@ -6420,7 +6684,7 @@ $(CHECK_BINS:%=$(BIN_DIR)/%) : $$(subst $(BIN_DIR),$(BUILD_DIR),$$@).c \
        gcc -g -o $@ $< $(@:$(BIN_DIR)/check_%=$(BUILD_DIR)/%.c) \
                $(patsubst %,$(BUILD_DIR)/%.c,$($(subst $(BIN_DIR)/,,$@_MODS)))\
                $(CHECK_LIBS:%=-l%)
-# todo: clean up the required modules to
+# TODO: clean up the required modules too
 $(CHECK_BINS:%=clean_%) :
        rm -f $(@:clean_%=$(BIN_DIR)/%) $(@:clean_%=$(BUILD_DIR)/%.c)