From 44bfae291b9ab5195eba15dc9c8f9bb99a7bbc2f Mon Sep 17 00:00:00 2001 From: Kenneth Geisshirt Date: Sat, 31 Oct 2026 18:46:27 +0100 Subject: [PATCH 01/13] Add KC_SANITIZE build option Builds kc with AddressSanitizer and UndefinedBehaviorSanitizer, so the test suite reports memory errors, leaks (on Linux) and undefined behaviour as test failures. Only the kc target is instrumented; the solver library and generated simulators are built as before. Co-Authored-By: Claude Opus 5.5 --- CMakeLists.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 51f9085..513b36f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,6 +48,15 @@ add_executable(kc target_include_directories(kc PRIVATE src ${CMAKE_CURRENT_BINARY_DIR}) target_link_libraries(kc PRIVATE kcsolvers) +# Developer option: check kc itself for memory errors, leaks and undefined +# behaviour. Only kc is instrumented, so generated simulators link as usual. +option(KC_SANITIZE "Build kc with AddressSanitizer and UndefinedBehaviorSanitizer" OFF) +if(KC_SANITIZE) + set(sanitize -fsanitize=address,undefined -fno-sanitize-recover=undefined -fno-omit-frame-pointer) + target_compile_options(kc PRIVATE ${sanitize}) + target_link_options(kc PRIVATE ${sanitize}) +endif() + configure_file(kci.in ${CMAKE_CURRENT_BINARY_DIR}/kci @ONLY) install(TARGETS kc kcsolvers) From 31490f3948bf70d927b23d18a871599e316d77ec Mon Sep 17 00:00:00 2001 From: Kenneth Geisshirt Date: Sat, 31 Oct 2026 18:47:06 +0100 Subject: [PATCH 02/13] Mode 2: write the initial values of all species to in.dat The loop over the species called GetSpecNo with 0..n-1, but species are numbered from 1. The first init-val was read from symtable[-1] and the last species was missing, so the initial values were shifted by one. UndefinedBehaviorSanitizer reports the out-of-bounds index. The in.dat files of the 21 models listed in skip.txt for this defect are now tested; the others change in their init-val lines only. Co-Authored-By: Claude Opus 5.5 --- src/waves.c | 2 +- test/expected/H2O2.des.m2/in.dat | 2 +- test/expected/atmos1.des.m2/in.dat | 2 +- test/expected/burst-2par.des.m2/in.dat | 14 ++++++++++++ test/expected/burst.des.m2/in.dat | 14 ++++++++++++ test/expected/burst.kcd.m2/in.dat | 14 ++++++++++++ test/expected/burst3.13.m2/in.dat | 14 ++++++++++++ test/expected/burst3.des.m2/in.dat | 14 ++++++++++++ test/expected/enzyme1.des.m2/in.dat | 2 +- test/expected/enzyme2.des.m2/in.dat | 2 +- test/expected/farrow.des.m2/in.dat | 2 +- test/expected/fozone.des.m2/in.dat | 2 +- test/expected/glyco.des.m2/in.dat | 12 ++++++++++ test/expected/gs.des.m2/in.dat | 10 +++++++++ test/expected/gtf.des.m2/in.dat | 31 ++++++++++++++++++++++++++ test/expected/hbry1.des.m2/in.dat | 13 +++++++++++ test/expected/hbry2.des.m2/in.dat | 13 +++++++++++ test/expected/hsn90.des.m2/in.dat | 12 ++++++++++ test/expected/knwang.des.m2/in.dat | 12 ++++++++++ test/expected/lotka.des.m2/in.dat | 2 +- test/expected/op.des.m2/in.dat | 12 ++++++++++ test/expected/open.des.m2/in.dat | 12 ++++++++++ test/expected/ore.kc.m2/in.dat | 11 +++++++++ test/expected/ore1.kc.m2/in.dat | 11 +++++++++ test/expected/ore2.des.m2/in.dat | 11 +++++++++ test/expected/reak.m2/in.dat | 22 ++++++++++++++++++ test/expected/real.des.m2/in.dat | 17 ++++++++++++++ test/expected/shn90.des.m2/in.dat | 13 +++++++++++ test/expected/split.des.m2/in.dat | 11 +++++++++ test/expected/test1.des.m2/in.dat | 2 +- test/expected/test10a.des.m2/in.dat | 2 +- test/expected/test10b.des.m2/in.dat | 2 +- test/expected/test12.des.m2/in.dat | 2 +- test/expected/test14a.des.m2/in.dat | 2 +- test/expected/test14b.des.m2/in.dat | 2 +- test/expected/test2.des.m2/in.dat | 2 +- test/expected/test3.des.m2/in.dat | 2 +- test/expected/test4.des.m2/in.dat | 2 +- test/expected/test6.des.m2/in.dat | 2 +- test/expected/test9.des.m2/in.dat | 2 +- test/skip.txt | 23 ------------------- 41 files changed, 312 insertions(+), 42 deletions(-) create mode 100644 test/expected/burst-2par.des.m2/in.dat create mode 100644 test/expected/burst.des.m2/in.dat create mode 100644 test/expected/burst.kcd.m2/in.dat create mode 100644 test/expected/burst3.13.m2/in.dat create mode 100644 test/expected/burst3.des.m2/in.dat create mode 100644 test/expected/glyco.des.m2/in.dat create mode 100644 test/expected/gs.des.m2/in.dat create mode 100644 test/expected/gtf.des.m2/in.dat create mode 100644 test/expected/hbry1.des.m2/in.dat create mode 100644 test/expected/hbry2.des.m2/in.dat create mode 100644 test/expected/hsn90.des.m2/in.dat create mode 100644 test/expected/knwang.des.m2/in.dat create mode 100644 test/expected/op.des.m2/in.dat create mode 100644 test/expected/open.des.m2/in.dat create mode 100644 test/expected/ore.kc.m2/in.dat create mode 100644 test/expected/ore1.kc.m2/in.dat create mode 100644 test/expected/ore2.des.m2/in.dat create mode 100644 test/expected/reak.m2/in.dat create mode 100644 test/expected/real.des.m2/in.dat create mode 100644 test/expected/shn90.des.m2/in.dat create mode 100644 test/expected/split.des.m2/in.dat diff --git a/src/waves.c b/src/waves.c index ff1a85e..42e8629 100644 --- a/src/waves.c +++ b/src/waves.c @@ -347,7 +347,7 @@ void Waves(FILE* code_h, FILE* code_c, FILE* code_ini) { if (GetError()==NotFound) temp=10.0; fprintf(code_ini, "period..= %e\n", temp); for(i=0; i Date: Sat, 31 Oct 2026 18:49:22 +0100 Subject: [PATCH 03/13] Fix the derivative of ln TreeDerive had no case for ln, so the chain-rule factor stayed an empty node, which reads as the constant 0: d ln(u)/dx came out as 0 instead of u'/u. The new test model derivatives1 covers the derivatives of ln, log, exp, sin, cos and f^g. Its mode 1 Jacobian was checked by hand. Co-Authored-By: Claude Opus 5.5 --- src/symbmath.c | 9 ++ test/derivatives1.des | 11 ++ test/expected/derivatives1.des.m1/stderr | 0 test/expected/derivatives1.des.m1/stdout | 63 +++++++++ test/expected/derivatives1.des.m2/in.dat | 8 ++ test/expected/derivatives1.des.m2/model.c | 122 ++++++++++++++++++ test/expected/derivatives1.des.m2/model.h | 14 ++ test/expected/derivatives1.des.m2/stderr | 2 + test/expected/derivatives1.des.m2/stdout | 8 ++ test/expected/derivatives1.des.m3/model.c | 84 ++++++++++++ test/expected/derivatives1.des.m3/model.h | 17 +++ test/expected/derivatives1.des.m3/sim.last | 1 + test/expected/derivatives1.des.m3/stderr | 0 test/expected/derivatives1.des.m3/stdout | 8 ++ test/expected/derivatives1.des.m4/model.f | 0 test/expected/derivatives1.des.m4/stderr | 1 + test/expected/derivatives1.des.m4/stdout | 8 ++ test/expected/derivatives1.des.m5/kcm5const.p | 0 test/expected/derivatives1.des.m5/kcm5proc.p | 0 test/expected/derivatives1.des.m5/stderr | 1 + test/expected/derivatives1.des.m5/stdout | 8 ++ 21 files changed, 365 insertions(+) create mode 100644 test/derivatives1.des create mode 100644 test/expected/derivatives1.des.m1/stderr create mode 100644 test/expected/derivatives1.des.m1/stdout create mode 100644 test/expected/derivatives1.des.m2/in.dat create mode 100644 test/expected/derivatives1.des.m2/model.c create mode 100644 test/expected/derivatives1.des.m2/model.h create mode 100644 test/expected/derivatives1.des.m2/stderr create mode 100644 test/expected/derivatives1.des.m2/stdout create mode 100644 test/expected/derivatives1.des.m3/model.c create mode 100644 test/expected/derivatives1.des.m3/model.h create mode 100644 test/expected/derivatives1.des.m3/sim.last create mode 100644 test/expected/derivatives1.des.m3/stderr create mode 100644 test/expected/derivatives1.des.m3/stdout create mode 100644 test/expected/derivatives1.des.m4/model.f create mode 100644 test/expected/derivatives1.des.m4/stderr create mode 100644 test/expected/derivatives1.des.m4/stdout create mode 100644 test/expected/derivatives1.des.m5/kcm5const.p create mode 100644 test/expected/derivatives1.des.m5/kcm5proc.p create mode 100644 test/expected/derivatives1.des.m5/stderr create mode 100644 test/expected/derivatives1.des.m5/stdout diff --git a/src/symbmath.c b/src/symbmath.c index 4938713..c8d02f5 100644 --- a/src/symbmath.c +++ b/src/symbmath.c @@ -882,6 +882,15 @@ void TreeDerive(Tree res, Tree t, char* name) { fprintf(stderr, "TreeDerive: dAcosh/dx not implemented\n"); tree_error=4; break; + case Ln: + res->data.oper.right->tag=Oper; + res->data.oper.right->data.oper.op=Div; + res->data.oper.right->data.oper.left=TreeCreate(); + res->data.oper.right->data.oper.right=TreeCreate(); + res->data.oper.right->data.oper.left->tag=Konst; + res->data.oper.right->data.oper.left->data.value=1.0; + TreeCpy(res->data.oper.right->data.oper.right, t->data.func.right); + break; case Log: res->data.oper.right->tag=Oper; res->data.oper.right->data.oper.op=Div; diff --git a/test/derivatives1.des b/test/derivatives1.des new file mode 100644 index 0000000..88f6695 --- /dev/null +++ b/test/derivatives1.des @@ -0,0 +1,11 @@ +etime = 1.0; + +u1' = ln(u1); +u2' = log(u2); +u3' = exp(u3)*sin(u3)*cos(u3); +u4' = u1^u2; + +u1(0) = 2.0; +u2(0) = 2.0; +u3(0) = 0.5; +u4(0) = 0.0; diff --git a/test/expected/derivatives1.des.m1/stderr b/test/expected/derivatives1.des.m1/stderr new file mode 100644 index 0000000..e69de29 diff --git a/test/expected/derivatives1.des.m1/stdout b/test/expected/derivatives1.des.m1/stdout new file mode 100644 index 0000000..78f9c72 --- /dev/null +++ b/test/expected/derivatives1.des.m1/stdout @@ -0,0 +1,63 @@ +kc v1.10, (C) Copyright by Kenneth Geisshirt and Keld Nielsen, 1992-1996 +Species used (*=dyn. var.): + *u1 + *u2 + *u3 + *u4 +Constants declared: + etime = 1.000000e+00 +The Jacobian matrix is: +J(1, 1) = 5.00000000000000e-01 +J(1, 2) = 0.00000000000000e+00 +J(1, 3) = 0.00000000000000e+00 +J(1, 4) = 0.00000000000000e+00 +J(2, 1) = 0.00000000000000e+00 +J(2, 2) = 2.17147240950000e-01 +J(2, 3) = 0.00000000000000e+00 +J(2, 4) = 0.00000000000000e+00 +J(3, 1) = 0.00000000000000e+00 +J(3, 2) = 0.00000000000000e+00 +J(3, 3) = 1.58448345995801e+00 +J(3, 4) = 0.00000000000000e+00 +J(4, 1) = 4.00000000000000e+00 +J(4, 2) = 2.77258872223978e+00 +J(4, 3) = 0.00000000000000e+00 +J(4, 4) = 0.00000000000000e+00 + +The eigenvalues are: + (1.5844834600e+00, 0.0000000000e+00) + (5.0000000000e-01, 0.0000000000e+00) + (2.1714724095e-01, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + +The eigenvectors are: + (0.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (1.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + + (1.2500000000e-01, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (1.0000000000e+00, 0.0000000000e+00) + + (0.0000000000e+00, 0.0000000000e+00) + (7.8319311915e-02, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (1.0000000000e+00, 0.0000000000e+00) + + (0.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (1.0000000000e+00, 0.0000000000e+00) + +No. 0,REAL part: Left 0.000000e+00, Right 0.000000e+00, Diff. 0.000000e+00 +No. 0,IM part: Left 0.000000e+00, Right 0.000000e+00, Diff 0.000000e+00 +No. 1,REAL part: Left 0.000000e+00, Right 0.000000e+00, Diff. 0.000000e+00 +No. 1,IM part: Left 0.000000e+00, Right 0.000000e+00, Diff 0.000000e+00 +No. 2,REAL part: Left 0.000000e+00, Right 0.000000e+00, Diff. 0.000000e+00 +No. 2,IM part: Left 0.000000e+00, Right 0.000000e+00, Diff 0.000000e+00 +No. 3,REAL part: Left 0.000000e+00, Right 0.000000e+00, Diff. 0.000000e+00 +No. 3,IM part: Left 0.000000e+00, Right 0.000000e+00, Diff 0.000000e+00 + +The eigenvalues diff --git a/test/expected/derivatives1.des.m2/in.dat b/test/expected/derivatives1.des.m2/in.dat new file mode 100644 index 0000000..fa61c4a --- /dev/null +++ b/test/expected/derivatives1.des.m2/in.dat @@ -0,0 +1,8 @@ +dt......= 2.000000e+00 +L.......= 1.000000e+02 +prefix..= test +max_t...= 2.000000e+02 +pt1.....= 100 +pt2.....= 100 +period..= 1.000000e+01 +noise...= 1.000000e-03 diff --git a/test/expected/derivatives1.des.m2/model.c b/test/expected/derivatives1.des.m2/model.c new file mode 100644 index 0000000..e7df6fe --- /dev/null +++ b/test/expected/derivatives1.des.m2/model.c @@ -0,0 +1,122 @@ +/* ######################## +*/ + +#include +#include "model.h" +void init_diff_const(void) { +} /* init_diff_const */ + +double reac(double* S, int l) { + double u1; + double u2; + double u3; + double u4; + u1=S[1]; + u2=S[2]; + u3=S[3]; + u4=S[4]; + switch (l) { + case 0: return (log(u1)); +break; + case 1: return (log10(u2)); +break; + case 2: return (((exp(u3)*sin(u3))*cos(u3))); +break; + case 3: return ((pow(u1,u2))); +break; + } /* switch */ +} /* reac */ +void eval(double S[equa], double F[equa]) { + double u1; + double u2; + double u3; + double u4; + u1=S[0]; + u2=S[1]; + u3=S[2]; + u4=S[3]; + F[0] = log(u1); + F[1] = log10(u2); + F[2] = ((exp(u3)*sin(u3))*cos(u3)); + F[3] = (pow(u1,u2)); +} /* eval */ +void calc_jac(double S[equa], double tk, double R[equa], double Jac[equa+1][equa+1]) +{ + double u1; + double u2; + double u3; + double u4; + u1=S[0]; + u2=S[1]; + u3=S[2]; + u4=S[3]; +Jac[1][1]=tk*((1.000000e+00/u1))-(1+4*R[0]); +Jac[1][2]=tk*(0.000000e+00); +Jac[1][3]=tk*(0.000000e+00); +Jac[1][4]=tk*(0.000000e+00); +Jac[2][1]=tk*(0.000000e+00); +Jac[2][2]=tk*((4.342945e-01/u2))-(1+4*R[1]); +Jac[2][3]=tk*(0.000000e+00); +Jac[2][4]=tk*(0.000000e+00); +Jac[3][1]=tk*(0.000000e+00); +Jac[3][2]=tk*(0.000000e+00); +Jac[3][3]=tk*(((((exp(u3)*sin(u3))+(exp(u3)*cos(u3)))*cos(u3))+( +(exp(u3)*sin(u3))*(-(sin(u3))))))-(1+4*R[2]); +Jac[3][4]=tk*(0.000000e+00); +Jac[4][1]=tk*(((pow(u1,(u2-1.000000e+00)))*u2)); +Jac[4][2]=tk*(((pow(u1,u2))*log(u1))); +Jac[4][3]=tk*(0.000000e+00); +Jac[4][4]=tk*(0.000000e+00)-(1+4*R[3]); +} +double reac_F(double S[equa], double K[equa], double R[equa], double tk, int l) { + double u1; + double u2; + double u3; + double u4; + u1=S[0]; + u2=S[1]; + u3=S[2]; + u4=S[3]; +switch (l) { +case 1: +return (tk*(log(u1))-S[0]*(1+4*R[0])+K[0]); +break; +case 2: +return (tk*(log10(u2))-S[1]*(1+4*R[1])+K[1]); +break; +case 3: +return (tk*(((exp(u3)*sin(u3))*cos(u3)))-S[2]*(1+4*R[2])+K[2]); +break; +case 4: +return (tk*((pow(u1,u2)))-S[3]*(1+4*R[3])+K[3]); +break; +} +} +void calc_jac2(double S[equa], double Jac[equa][equa]) +{ +double u1; +double u2; +double u3; +double u4; +u1=S[0]; +u2=S[1]; +u3=S[2]; +u4=S[3]; +Jac[0][0]=(1.000000e+00/u1); +Jac[0][1]=0.000000e+00; +Jac[0][2]=0.000000e+00; +Jac[0][3]=0.000000e+00; +Jac[1][0]=0.000000e+00; +Jac[1][1]=(4.342945e-01/u2); +Jac[1][2]=0.000000e+00; +Jac[1][3]=0.000000e+00; +Jac[2][0]=0.000000e+00; +Jac[2][1]=0.000000e+00; +Jac[2][2]=((((exp(u3)*sin(u3))+(exp(u3)*cos(u3)))*cos(u3))+( +(exp(u3)*sin(u3))*(-(sin(u3))))); +Jac[2][3]=0.000000e+00; +Jac[3][0]=((pow(u1,(u2-1.000000e+00)))*u2); +Jac[3][1]=((pow(u1,u2))*log(u1)); +Jac[3][2]=0.000000e+00; +Jac[3][3]=0.000000e+00; +} diff --git a/test/expected/derivatives1.des.m2/model.h b/test/expected/derivatives1.des.m2/model.h new file mode 100644 index 0000000..ffc4080 --- /dev/null +++ b/test/expected/derivatives1.des.m2/model.h @@ -0,0 +1,14 @@ +/* ######################## +*/ + +#define n_grids 0 +#define m_grids 0 +#define equa 4 + +extern void init_diff_const(void); +double D[equa]; +extern double reac(double*, int); +extern void eval(double *, double *); +void calc_jac(double S[equa], double tk, double R[equa], double Jac[equa+1][equa+1]); +extern double reac_F(double S[equa], double K[equa], double R[equa], double tk, int l); +void calc_jac2(double S[equa], double Jac[equa][equa]); diff --git a/test/expected/derivatives1.des.m2/stderr b/test/expected/derivatives1.des.m2/stderr new file mode 100644 index 0000000..6d491b9 --- /dev/null +++ b/test/expected/derivatives1.des.m2/stderr @@ -0,0 +1,2 @@ +ERROR: The constant ngrid is not defined! +ERROR: The constant mgrid is not defined! diff --git a/test/expected/derivatives1.des.m2/stdout b/test/expected/derivatives1.des.m2/stdout new file mode 100644 index 0000000..f728da3 --- /dev/null +++ b/test/expected/derivatives1.des.m2/stdout @@ -0,0 +1,8 @@ +kc v1.10, (C) Copyright by Kenneth Geisshirt and Keld Nielsen, 1992-1996 +Species used (*=dyn. var.): + *u1 + *u2 + *u3 + *u4 +Constants declared: + etime = 1.000000e+00 diff --git a/test/expected/derivatives1.des.m3/model.c b/test/expected/derivatives1.des.m3/model.c new file mode 100644 index 0000000..467d2d2 --- /dev/null +++ b/test/expected/derivatives1.des.m3/model.c @@ -0,0 +1,84 @@ +/********************************************* + WARNING: This file was generated by kc v1.10 + CopyWrong by Kenneth Geisshirt + ######################## +**********************************************/ +#include "model.h" +#include +#include +void reac(double* S_, double* v_) { +int j_; +double u1; +double u2; +double u3; +double u4; +u1=S_[0]; +u2=S_[1]; +u3=S_[2]; +u4=S_[3]; +v_[0]=(log(u1)); +v_[1]=(log10(u2)); +v_[2]=(((exp(u3)*sin(u3))*cos(u3))); +v_[3]=((pow(u1,u2))); +} +void jacobi(double *S_){ +int j_; +double u1; +double u2; +double u3; +double u4; +u1=S_[0]; +u2=S_[1]; +u3=S_[2]; +u4=S_[3]; +jacobi_matx[0][0]=(1.000000e+00/u1); +jacobi_matx[1][1]=(4.342945e-01/u2); +jacobi_matx[2][2]=((((exp(u3)*sin(u3))+(exp(u3)*cos(u3)))*cos(u3))+( +(exp(u3)*sin(u3))*(-(sin(u3))))); +jacobi_matx[3][0]=((pow(u1,(u2-1.000000e+00)))*u2); +jacobi_matx[3][1]=((pow(u1,u2))*log(u1)); +} +void InitValues(void) { +FILE *infile_; +x_[0]=2.000000e+00; +do_print[0]=1; +x_[1]=2.000000e+00; +do_print[1]=1; +x_[2]=5.000000e-01; +do_print[2]=1; +x_[3]=0.000000e+00; +do_print[3]=1; +epsmin_=0.000000e+00; +dtime_=2.000000e+00; +prnmode_=0; +etime_=1.000000e+00; +stime_=0.000000e+00; +htime_=1.000000e+00; +epsr_=1.000000e-05; +epsa_=1.000000e-10; +epse_=1.000000e-10; +solver_=1; +step_adjustment_factor=9.000000e-01; +steplimit_increase=1.500000e+00; +steplimit_decrease=5.000000e-01; +htimemin_=1.000000e-20; +begin_print=0.000000e+00; +scaling_=0; +debug_=1; +(void) strcpy(species[0], "u1"); +(void) strcpy(species[1], "u2"); +(void) strcpy(species[2], "u3"); +(void) strcpy(species[3], "u4"); +(void) strcpy(datafilename_,"kinwrkda"); +jacobi_matx[0][1]=0.000000e+00; +jacobi_matx[0][2]=0.000000e+00; +jacobi_matx[0][3]=0.000000e+00; +jacobi_matx[1][0]=0.000000e+00; +jacobi_matx[1][2]=0.000000e+00; +jacobi_matx[1][3]=0.000000e+00; +jacobi_matx[2][0]=0.000000e+00; +jacobi_matx[2][1]=0.000000e+00; +jacobi_matx[2][3]=0.000000e+00; +jacobi_matx[3][2]=0.000000e+00; +jacobi_matx[3][3]=0.000000e+00; +} diff --git a/test/expected/derivatives1.des.m3/model.h b/test/expected/derivatives1.des.m3/model.h new file mode 100644 index 0000000..d39f6e5 --- /dev/null +++ b/test/expected/derivatives1.des.m3/model.h @@ -0,0 +1,17 @@ +/********************************************* + WARNING: This file was generated by kc v1.10 + CopyWrong by Kenneth Geisshirt + ######################## +**********************************************/ +#ifndef _MODEL_HEADER_ +#define _MODEL_HEADER_ +#define equa 4 +#undef _DO_PERT_ +#undef PRINT_ON_SCREEN +double x_[equa],x_pert[equa],xscal_[equa]; +int do_print[equa]; +char species[equa][25]; +extern void reac(double *, double *); +extern void jacobi(double *); +extern void InitValues(void); +#endif diff --git a/test/expected/derivatives1.des.m3/sim.last b/test/expected/derivatives1.des.m3/sim.last new file mode 100644 index 0000000..64545c6 --- /dev/null +++ b/test/expected/derivatives1.des.m3/sim.last @@ -0,0 +1 @@ +1.000000e+00 2.872463e+00 2.334336e+00 1.463672e+00 6.990385e+00 diff --git a/test/expected/derivatives1.des.m3/stderr b/test/expected/derivatives1.des.m3/stderr new file mode 100644 index 0000000..e69de29 diff --git a/test/expected/derivatives1.des.m3/stdout b/test/expected/derivatives1.des.m3/stdout new file mode 100644 index 0000000..f728da3 --- /dev/null +++ b/test/expected/derivatives1.des.m3/stdout @@ -0,0 +1,8 @@ +kc v1.10, (C) Copyright by Kenneth Geisshirt and Keld Nielsen, 1992-1996 +Species used (*=dyn. var.): + *u1 + *u2 + *u3 + *u4 +Constants declared: + etime = 1.000000e+00 diff --git a/test/expected/derivatives1.des.m4/model.f b/test/expected/derivatives1.des.m4/model.f new file mode 100644 index 0000000..e69de29 diff --git a/test/expected/derivatives1.des.m4/stderr b/test/expected/derivatives1.des.m4/stderr new file mode 100644 index 0000000..68a037d --- /dev/null +++ b/test/expected/derivatives1.des.m4/stderr @@ -0,0 +1 @@ +Continuation program aborted: Wrong number of parameters - should be between 2 and 40. diff --git a/test/expected/derivatives1.des.m4/stdout b/test/expected/derivatives1.des.m4/stdout new file mode 100644 index 0000000..f728da3 --- /dev/null +++ b/test/expected/derivatives1.des.m4/stdout @@ -0,0 +1,8 @@ +kc v1.10, (C) Copyright by Kenneth Geisshirt and Keld Nielsen, 1992-1996 +Species used (*=dyn. var.): + *u1 + *u2 + *u3 + *u4 +Constants declared: + etime = 1.000000e+00 diff --git a/test/expected/derivatives1.des.m5/kcm5const.p b/test/expected/derivatives1.des.m5/kcm5const.p new file mode 100644 index 0000000..e69de29 diff --git a/test/expected/derivatives1.des.m5/kcm5proc.p b/test/expected/derivatives1.des.m5/kcm5proc.p new file mode 100644 index 0000000..e69de29 diff --git a/test/expected/derivatives1.des.m5/stderr b/test/expected/derivatives1.des.m5/stderr new file mode 100644 index 0000000..159afbd --- /dev/null +++ b/test/expected/derivatives1.des.m5/stderr @@ -0,0 +1 @@ +KNCont: Wrong number of parameters - should be either 1 or 2. diff --git a/test/expected/derivatives1.des.m5/stdout b/test/expected/derivatives1.des.m5/stdout new file mode 100644 index 0000000..f728da3 --- /dev/null +++ b/test/expected/derivatives1.des.m5/stdout @@ -0,0 +1,8 @@ +kc v1.10, (C) Copyright by Kenneth Geisshirt and Keld Nielsen, 1992-1996 +Species used (*=dyn. var.): + *u1 + *u2 + *u3 + *u4 +Constants declared: + etime = 1.000000e+00 From 5dddad10ab08a5779c809d6ae210c4566a271543 Mon Sep 17 00:00:00 2001 From: Kenneth Geisshirt Date: Sat, 31 Oct 2026 18:51:59 +0100 Subject: [PATCH 04/13] Fix the derivatives of tan, tanh and the inverse functions Most derivatives of functions built their result in the wrong nodes: - tan, tanh: cos(u)/cosh(u) was written over the Pow node, giving u'/(u*2) instead of u'/cos(u)^2 - asinh: the exponent 0.5 was set on the wrong node; the result was u' - acos: derived into a NULL pointer, so kc crashed - acosh: not implemented, the result was 0 - atan, atanh: correct only because a second derivation through the wrong union member got a NULL tree and did nothing These cases now use small node builders and state the rule they implement. The new test model derivatives2 covers all of them; its mode 1 Jacobian matches numerical differentiation. Co-Authored-By: Claude Opus 5.5 --- src/symbmath.c | 214 +++++-------- test/derivatives2.des | 19 ++ test/expected/derivatives2.des.m1/stderr | 0 test/expected/derivatives2.des.m1/stdout | 179 +++++++++++ test/expected/derivatives2.des.m2/in.dat | 8 + test/expected/derivatives2.des.m2/model.c | 288 ++++++++++++++++++ test/expected/derivatives2.des.m2/model.h | 14 + test/expected/derivatives2.des.m2/stderr | 2 + test/expected/derivatives2.des.m2/stdout | 12 + test/expected/derivatives2.des.m3/model.c | 167 ++++++++++ test/expected/derivatives2.des.m3/model.h | 17 ++ test/expected/derivatives2.des.m3/sim.last | 1 + test/expected/derivatives2.des.m3/stderr | 0 test/expected/derivatives2.des.m3/stdout | 12 + test/expected/derivatives2.des.m4/model.f | 0 test/expected/derivatives2.des.m4/stderr | 1 + test/expected/derivatives2.des.m4/stdout | 12 + test/expected/derivatives2.des.m5/kcm5const.p | 0 test/expected/derivatives2.des.m5/kcm5proc.p | 0 test/expected/derivatives2.des.m5/stderr | 1 + test/expected/derivatives2.des.m5/stdout | 12 + 21 files changed, 820 insertions(+), 139 deletions(-) create mode 100644 test/derivatives2.des create mode 100644 test/expected/derivatives2.des.m1/stderr create mode 100644 test/expected/derivatives2.des.m1/stdout create mode 100644 test/expected/derivatives2.des.m2/in.dat create mode 100644 test/expected/derivatives2.des.m2/model.c create mode 100644 test/expected/derivatives2.des.m2/model.h create mode 100644 test/expected/derivatives2.des.m2/stderr create mode 100644 test/expected/derivatives2.des.m2/stdout create mode 100644 test/expected/derivatives2.des.m3/model.c create mode 100644 test/expected/derivatives2.des.m3/model.h create mode 100644 test/expected/derivatives2.des.m3/sim.last create mode 100644 test/expected/derivatives2.des.m3/stderr create mode 100644 test/expected/derivatives2.des.m3/stdout create mode 100644 test/expected/derivatives2.des.m4/model.f create mode 100644 test/expected/derivatives2.des.m4/stderr create mode 100644 test/expected/derivatives2.des.m4/stdout create mode 100644 test/expected/derivatives2.des.m5/kcm5const.p create mode 100644 test/expected/derivatives2.des.m5/kcm5proc.p create mode 100644 test/expected/derivatives2.des.m5/stderr create mode 100644 test/expected/derivatives2.des.m5/stdout diff --git a/src/symbmath.c b/src/symbmath.c index c8d02f5..757a49d 100644 --- a/src/symbmath.c +++ b/src/symbmath.c @@ -567,9 +567,57 @@ void TreeSubstTree(Tree t, char *name, Tree value) { } /* else */ } /* TreeSubstTree */ +/* Builders for TreeDerive: unreduced nodes, the result is reduced once. */ +static Tree Op(TreeOper op, Tree left, Tree right) { + + Tree t=TreeCreate(); + + t->tag=Oper; + t->data.oper.op=op; + t->data.oper.left=left; + t->data.oper.right=right; + return t; +} /* Op */ + +static Tree Const(double value) { + + Tree t=TreeCreate(); + + t->tag=Konst; + t->data.value=value; + return t; +} /* Const */ + +static Tree Fun(Function fun, Tree arg) { + + Tree t=TreeCreate(); + + t->tag=Func; + t->data.func.fun=fun; + t->data.func.right=arg; + return t; +} /* Fun */ + +static Tree Neg(Tree arg) { + + Tree t=TreeCreate(); + + t->tag=NegSign; + t->data.right=arg; + return t; +} /* Neg */ + +static Tree Copy(Tree t) { + + Tree c=TreeCreate(); + + TreeCpy(c, t); + return c; +} /* Copy */ + void TreeDerive(Tree res, Tree t, char* name) { - Tree t1, t2, t3; + Tree t1, t2, t3, u; tree_error=0; if (t!=NULL) { @@ -693,6 +741,7 @@ void TreeDerive(Tree res, Tree t, char* name) { } /* switch */ break; case Func: + u=t->data.func.right; res->tag=Oper; res->data.oper.op=Mul; res->data.oper.left=TreeCreate(); @@ -732,155 +781,42 @@ void TreeDerive(Tree res, Tree t, char* name) { res->data.oper.right->data.func.right=TreeCreate(); TreeCpy(res->data.oper.right->data.func.right, t->data.func.right); break; - case Atan: + case Atan: /* u'/(1+u^2) */ res->data.oper.op=Div; - TreeDerive(res->data.oper.left, t->data.oper.right, name); - res->data.oper.right->tag=Oper; - res->data.oper.right->data.oper.op=Add; - res->data.oper.right->data.oper.left=TreeCreate(); - res->data.oper.right->data.oper.right=TreeCreate(); - res->data.oper.right->data.oper.left->tag=Konst; - res->data.oper.right->data.oper.left->data.value=1.0; - res->data.oper.right->data.oper.right->tag=Oper; - res->data.oper.right->data.oper.right->data.oper.op=Pow; - res->data.oper.right->data.oper.right->data.oper.left=TreeCreate(); - res->data.oper.right->data.oper.right->data.oper.right=TreeCreate(); - TreeCpy(res->data.oper.right->data.oper.right->data.oper.left, - t->data.func.right); - res->data.oper.right->data.oper.right->data.oper.right->tag=Konst; - res->data.oper.right->data.oper.right->data.oper.right->data.value - =2.0; + res->data.oper.right=Op(Add, Const(1.0), Op(Pow, Copy(u), Const(2.0))); break; - case Asinh: + case Atanh: /* u'/(1-u^2) */ res->data.oper.op=Div; - TreeDerive(res->data.oper.left, t->data.oper.right, name); - res->data.oper.right->tag=Oper; - res->data.oper.right->data.oper.op=Pow; - res->data.oper.right->data.oper.left=TreeCreate(); - res->data.oper.right->data.oper.right=TreeCreate(); - res->data.oper.right->data.oper.left->tag=Oper; - res->data.oper.right->data.oper.left->data.oper.op=Pow; - res->data.oper.right->data.oper.left->data.oper.left=TreeCreate(); - res->data.oper.right->data.oper.left->data.oper.right=TreeCreate(); - res->data.oper.right->data.oper.left->data.oper.left->tag=Oper; - res->data.oper.right->data.oper.left->data.oper.left->data.oper.op - =Add; - res->data.oper.right->data.oper.left->data.oper.left->data.oper.left - =TreeCreate(); - res->data.oper.right->data.oper.left->data.oper.left->data.oper.right - =TreeCreate(); - res->data.oper.right->data.oper.left->data.oper.left->data.oper.left->tag=Oper; - res->data.oper.right->data.oper.left->data.oper.left->data.oper.left->data.oper.op=Pow; - res->data.oper.right->data.oper.left->data.oper.left->data.oper.left->data.oper.left=TreeCreate(); - res->data.oper.right->data.oper.left->data.oper.left->data.oper.left->data.oper.right=TreeCreate(); - TreeCpy(res->data.oper.right->data.oper.left->data.oper.left->data.oper.left->data.oper.left, t->data.func.right); - res->data.oper.right->data.oper.left->data.oper.left->data.oper.left->data.oper.right->tag=Konst; - res->data.oper.right->data.oper.left->data.oper.left->data.oper.left->data.oper.right->data.value=2.0; - res->data.oper.right->data.oper.left->data.oper.left->data.oper.right->tag=Konst; - res->data.oper.right->data.oper.left->data.oper.left->data.oper.right->data.value=1.0; - res->data.oper.right->data.oper.left->data.oper.right->tag=Konst; - res->data.oper.right->data.oper.left->data.oper.right->data.value=0.5; + res->data.oper.right=Op(Sub, Const(1.0), Op(Pow, Copy(u), Const(2.0))); break; - case Atanh: - res->data.oper.op=Div; - TreeDerive(res->data.oper.left, t->data.oper.right, name); - res->data.oper.right->tag=Oper; - res->data.oper.right->data.oper.op=Sub; - res->data.oper.right->data.oper.left=TreeCreate(); - res->data.oper.right->data.oper.right=TreeCreate(); - res->data.oper.right->data.oper.left->tag=Konst; - res->data.oper.right->data.oper.left->data.value=1.0; - res->data.oper.right->data.oper.right->tag=Oper; - res->data.oper.right->data.oper.right->data.oper.op=Pow; - res->data.oper.right->data.oper.right->data.oper.left=TreeCreate(); - res->data.oper.right->data.oper.right->data.oper.right=TreeCreate(); - TreeCpy(res->data.oper.right->data.oper.right->data.oper.left, - t->data.func.right); - res->data.oper.right->data.oper.right->data.oper.right->tag=Konst; - res->data.oper.right->data.oper.right->data.oper.right->data.value=2.0; - break; - case Tan: + case Asinh: /* u'/(u^2+1)^0.5 */ res->data.oper.op=Div; - TreeDerive(res->data.oper.left, t->data.oper.right, name); - res->data.oper.right->tag=Oper; - res->data.oper.right->data.oper.op=Pow; - res->data.oper.right->data.oper.right=TreeCreate(); - res->data.oper.right->data.oper.left=TreeCreate(); - res->data.oper.right->data.oper.left->tag=Func; - res->data.oper.right->data.func.fun=Cos; - res->data.oper.right->data.func.right=TreeCreate(); - TreeCpy(res->data.oper.right->data.func.right, t->data.func.right); - res->data.oper.right->data.oper.right->tag=Konst; - res->data.oper.right->data.oper.right->data.value=2.0; + res->data.oper.right=Op(Pow, Op(Add, Op(Pow, Copy(u), Const(2.0)), + Const(1.0)), Const(0.5)); break; - case Tanh: - res->data.oper.op=Div; - TreeDerive(res->data.oper.left, t->data.oper.right, name); - res->data.oper.right->tag=Oper; - res->data.oper.right->data.oper.op=Pow; - res->data.oper.right->data.oper.right=TreeCreate(); - res->data.oper.right->data.oper.left=TreeCreate(); - res->data.oper.right->data.oper.left->tag=Func; - res->data.oper.right->data.func.fun=Cosh; - res->data.oper.right->data.func.right=TreeCreate(); - TreeCpy(res->data.oper.right->data.func.right, t->data.func.right); - res->data.oper.right->data.oper.right->tag=Konst; - res->data.oper.right->data.oper.right->data.value=2.0; + case Acosh: /* u'/(u^2-1)^0.5 */ + res->data.oper.op=Div; + res->data.oper.right=Op(Pow, Op(Sub, Op(Pow, Copy(u), Const(2.0)), + Const(1.0)), Const(0.5)); break; - case Asin: + case Tan: /* u'/cos(u)^2 */ res->data.oper.op=Div; - res->data.oper.left=TreeCreate(); - res->data.oper.right=TreeCreate(); - TreeDerive(res->data.oper.left, t->data.func.right, name); - res->data.oper.right->tag=Oper; - res->data.oper.right->data.oper.op=Pow; - res->data.oper.right->data.oper.left=TreeCreate(); - res->data.oper.right->data.oper.right=TreeCreate(); - res->data.oper.right->data.oper.left->tag=Oper; - res->data.oper.right->data.oper.left->data.oper.op=Sub; - res->data.oper.right->data.oper.left->data.oper.left=TreeCreate(); - res->data.oper.right->data.oper.left->data.oper.right=TreeCreate(); - res->data.oper.right->data.oper.left->data.oper.left->tag=Konst; - res->data.oper.right->data.oper.left->data.oper.left->data.value=1.0; - res->data.oper.right->data.oper.left->data.oper.right->tag=Oper; - res->data.oper.right->data.oper.left->data.oper.right->data.oper.op=Pow; - res->data.oper.right->data.oper.left->data.oper.right->data.oper.left=TreeCreate(); - res->data.oper.right->data.oper.left->data.oper.right->data.oper.right=TreeCreate(); - TreeCpy(res->data.oper.right->data.oper.left->data.oper.right->data.oper.left, t->data.func.right); - res->data.oper.right->data.oper.left->data.oper.right->data.oper.right->tag=Konst; - res->data.oper.right->data.oper.left->data.oper.right->data.oper.right->data.value=2.0; - res->data.oper.right->data.oper.right->tag=Konst; - res->data.oper.right->data.oper.right->data.value=0.5; + res->data.oper.right=Op(Pow, Fun(Cos, Copy(u)), Const(2.0)); break; - case Acos: + case Tanh: /* u'/cosh(u)^2 */ res->data.oper.op=Div; - res->data.oper.left=TreeCreate(); - res->data.oper.right=TreeCreate(); - res->data.oper.left->tag=NegSign; - TreeDerive(res->data.oper.left->data.right, t->data.func.right, name); - res->data.oper.right->tag=Oper; - res->data.oper.right->data.oper.op=Pow; - res->data.oper.right->data.oper.left=TreeCreate(); - res->data.oper.right->data.oper.right=TreeCreate(); - res->data.oper.right->data.oper.left->tag=Oper; - res->data.oper.right->data.oper.left->data.oper.op=Sub; - res->data.oper.right->data.oper.left->data.oper.left=TreeCreate(); - res->data.oper.right->data.oper.left->data.oper.right=TreeCreate(); - res->data.oper.right->data.oper.left->data.oper.left->tag=Konst; - res->data.oper.right->data.oper.left->data.oper.left->data.value=1.0; - res->data.oper.right->data.oper.left->data.oper.right->tag=Oper; - res->data.oper.right->data.oper.left->data.oper.right->data.oper.op=Pow; - res->data.oper.right->data.oper.left->data.oper.right->data.oper.left=TreeCreate(); - res->data.oper.right->data.oper.left->data.oper.right->data.oper.right=TreeCreate(); - TreeCpy(res->data.oper.right->data.oper.left->data.oper.right->data.oper.left, t->data.func.right); - res->data.oper.right->data.oper.left->data.oper.right->data.oper.right->tag=Konst; - res->data.oper.right->data.oper.left->data.oper.right->data.oper.right->data.value=2.0; - res->data.oper.right->data.oper.right->tag=Konst; - res->data.oper.right->data.oper.right->data.value=0.5; + res->data.oper.right=Op(Pow, Fun(Cosh, Copy(u)), Const(2.0)); break; - case Acosh: - fprintf(stderr, "TreeDerive: dAcosh/dx not implemented\n"); - tree_error=4; + case Asin: /* u'/(1-u^2)^0.5 */ + res->data.oper.op=Div; + res->data.oper.right=Op(Pow, Op(Sub, Const(1.0), + Op(Pow, Copy(u), Const(2.0))), Const(0.5)); + break; + case Acos: /* -u'/(1-u^2)^0.5 */ + res->data.oper.op=Div; + res->data.oper.left=Neg(res->data.oper.left); + res->data.oper.right=Op(Pow, Op(Sub, Const(1.0), + Op(Pow, Copy(u), Const(2.0))), Const(0.5)); break; case Ln: res->data.oper.right->tag=Oper; diff --git a/test/derivatives2.des b/test/derivatives2.des new file mode 100644 index 0000000..4cfaa88 --- /dev/null +++ b/test/derivatives2.des @@ -0,0 +1,19 @@ +etime = 1.0; + +u1' = -tan(u1); +u2' = -tanh(u2); +u3' = -asin(u3); +u4' = acos(u4) - 1.0; +u5' = -atan(u5); +u6' = -asinh(u6); +u7' = 1.0 - acosh(u7); +u8' = -atanh(u8); + +u1(0) = 0.5; +u2(0) = 0.5; +u3(0) = 0.5; +u4(0) = 0.5; +u5(0) = 0.5; +u6(0) = 0.5; +u7(0) = 2.0; +u8(0) = 0.5; diff --git a/test/expected/derivatives2.des.m1/stderr b/test/expected/derivatives2.des.m1/stderr new file mode 100644 index 0000000..e69de29 diff --git a/test/expected/derivatives2.des.m1/stdout b/test/expected/derivatives2.des.m1/stdout new file mode 100644 index 0000000..292d344 --- /dev/null +++ b/test/expected/derivatives2.des.m1/stdout @@ -0,0 +1,179 @@ +kc v1.10, (C) Copyright by Kenneth Geisshirt and Keld Nielsen, 1992-1996 +Species used (*=dyn. var.): + *u1 + *u2 + *u3 + *u4 + *u5 + *u6 + *u7 + *u8 +Constants declared: + etime = 1.000000e+00 +The Jacobian matrix is: +J(1, 1) = -1.29844641040952e+00 +J(1, 2) = -0.00000000000000e+00 +J(1, 3) = -0.00000000000000e+00 +J(1, 4) = -0.00000000000000e+00 +J(1, 5) = -0.00000000000000e+00 +J(1, 6) = -0.00000000000000e+00 +J(1, 7) = -0.00000000000000e+00 +J(1, 8) = -0.00000000000000e+00 +J(2, 1) = -0.00000000000000e+00 +J(2, 2) = -7.86447732965928e-01 +J(2, 3) = -0.00000000000000e+00 +J(2, 4) = -0.00000000000000e+00 +J(2, 5) = -0.00000000000000e+00 +J(2, 6) = -0.00000000000000e+00 +J(2, 7) = -0.00000000000000e+00 +J(2, 8) = -0.00000000000000e+00 +J(3, 1) = -0.00000000000000e+00 +J(3, 2) = -0.00000000000000e+00 +J(3, 3) = -1.15470053837925e+00 +J(3, 4) = -0.00000000000000e+00 +J(3, 5) = -0.00000000000000e+00 +J(3, 6) = -0.00000000000000e+00 +J(3, 7) = -0.00000000000000e+00 +J(3, 8) = -0.00000000000000e+00 +J(4, 1) = 0.00000000000000e+00 +J(4, 2) = 0.00000000000000e+00 +J(4, 3) = 0.00000000000000e+00 +J(4, 4) = -1.15470053837925e+00 +J(4, 5) = 0.00000000000000e+00 +J(4, 6) = 0.00000000000000e+00 +J(4, 7) = 0.00000000000000e+00 +J(4, 8) = 0.00000000000000e+00 +J(5, 1) = -0.00000000000000e+00 +J(5, 2) = -0.00000000000000e+00 +J(5, 3) = -0.00000000000000e+00 +J(5, 4) = -0.00000000000000e+00 +J(5, 5) = -8.00000000000000e-01 +J(5, 6) = -0.00000000000000e+00 +J(5, 7) = -0.00000000000000e+00 +J(5, 8) = -0.00000000000000e+00 +J(6, 1) = -0.00000000000000e+00 +J(6, 2) = -0.00000000000000e+00 +J(6, 3) = -0.00000000000000e+00 +J(6, 4) = -0.00000000000000e+00 +J(6, 5) = -0.00000000000000e+00 +J(6, 6) = -8.94427190999916e-01 +J(6, 7) = -0.00000000000000e+00 +J(6, 8) = -0.00000000000000e+00 +J(7, 1) = 0.00000000000000e+00 +J(7, 2) = 0.00000000000000e+00 +J(7, 3) = 0.00000000000000e+00 +J(7, 4) = 0.00000000000000e+00 +J(7, 5) = 0.00000000000000e+00 +J(7, 6) = 0.00000000000000e+00 +J(7, 7) = -5.77350269189626e-01 +J(7, 8) = 0.00000000000000e+00 +J(8, 1) = -0.00000000000000e+00 +J(8, 2) = -0.00000000000000e+00 +J(8, 3) = -0.00000000000000e+00 +J(8, 4) = -0.00000000000000e+00 +J(8, 5) = -0.00000000000000e+00 +J(8, 6) = -0.00000000000000e+00 +J(8, 7) = -0.00000000000000e+00 +J(8, 8) = -1.33333333333333e+00 + +The eigenvalues are: + (-5.7735026919e-01, 0.0000000000e+00) + (-7.8644773297e-01, 0.0000000000e+00) + (-8.0000000000e-01, 0.0000000000e+00) + (-8.9442719100e-01, 0.0000000000e+00) + (-1.1547005384e+00, 0.0000000000e+00) + (-1.1547005384e+00, 0.0000000000e+00) + (-1.2984464104e+00, 0.0000000000e+00) + (-1.3333333333e+00, 0.0000000000e+00) + +The eigenvectors are: + (0.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (1.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + + (0.0000000000e+00, 0.0000000000e+00) + (1.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + + (0.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (1.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + + (0.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (1.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + + (0.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (1.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + + (0.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (1.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + + (1.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + + (0.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (1.0000000000e+00, 0.0000000000e+00) + +No. 0,REAL part: Left 0.000000e+00, Right 0.000000e+00, Diff. 0.000000e+00 +No. 0,IM part: Left 0.000000e+00, Right 0.000000e+00, Diff 0.000000e+00 +No. 1,REAL part: Left -7.864477e-01, Right -7.864477e-01, Diff. 0.000000e+00 +No. 1,IM part: Left 0.000000e+00, Right 0.000000e+00, Diff 0.000000e+00 +No. 2,REAL part: Left 0.000000e+00, Right 0.000000e+00, Diff. 0.000000e+00 +No. 2,IM part: Left 0.000000e+00, Right 0.000000e+00, Diff 0.000000e+00 +No. 3,REAL part: Left 0.000000e+00, Right 0.000000e+00, Diff. 0.000000e+00 +No. 3,IM part: Left 0.000000e+00, Right 0.000000e+00, Diff 0.000000e+00 +No. 4,REAL part: Left 0.000000e+00, Right 0.000000e+00, Diff. 0.000000e+00 +No. 4,IM part: Left 0.000000e+00, Right 0.000000e+00, Diff 0.000000e+00 +No. 5,REAL part: Left 0.000000e+00, Right 0.000000e+00, Diff. 0.000000e+00 +No. 5,IM part: Left 0.000000e+00, Right 0.000000e+00, Diff 0.000000e+00 +No. 6,REAL part: Left 0.000000e+00, Right 0.000000e+00, Diff. 0.000000e+00 +No. 6,IM part: Left 0.000000e+00, Right 0.000000e+00, Diff 0.000000e+00 +No. 7,REAL part: Left -1.333333e+00, Right -1.333333e+00, Diff. 0.000000e+00 +No. 7,IM part: Left 0.000000e+00, Right 0.000000e+00, Diff 0.000000e+00 + +The eigenvalues diff --git a/test/expected/derivatives2.des.m2/in.dat b/test/expected/derivatives2.des.m2/in.dat new file mode 100644 index 0000000..fa61c4a --- /dev/null +++ b/test/expected/derivatives2.des.m2/in.dat @@ -0,0 +1,8 @@ +dt......= 2.000000e+00 +L.......= 1.000000e+02 +prefix..= test +max_t...= 2.000000e+02 +pt1.....= 100 +pt2.....= 100 +period..= 1.000000e+01 +noise...= 1.000000e-03 diff --git a/test/expected/derivatives2.des.m2/model.c b/test/expected/derivatives2.des.m2/model.c new file mode 100644 index 0000000..0b6618b --- /dev/null +++ b/test/expected/derivatives2.des.m2/model.c @@ -0,0 +1,288 @@ +/* ######################## +*/ + +#include +#include "model.h" +void init_diff_const(void) { +} /* init_diff_const */ + +double reac(double* S, int l) { + double u1; + double u2; + double u3; + double u4; + double u5; + double u6; + double u7; + double u8; + u1=S[1]; + u2=S[2]; + u3=S[3]; + u4=S[4]; + u5=S[5]; + u6=S[6]; + u7=S[7]; + u8=S[8]; + switch (l) { + case 0: return ((-(tan(u1)))); +break; + case 1: return ((-(tanh(u2)))); +break; + case 2: return ((-(asin(u3)))); +break; + case 3: return ((acos(u4)-1.000000e+00)); +break; + case 4: return ((-(atan(u5)))); +break; + case 5: return ((-(asinh(u6)))); +break; + case 6: return ((1.000000e+00-acosh(u7))); +break; + case 7: return ((-(atanh(u8)))); +break; + } /* switch */ +} /* reac */ +void eval(double S[equa], double F[equa]) { + double u1; + double u2; + double u3; + double u4; + double u5; + double u6; + double u7; + double u8; + u1=S[0]; + u2=S[1]; + u3=S[2]; + u4=S[3]; + u5=S[4]; + u6=S[5]; + u7=S[6]; + u8=S[7]; + F[0] = (-(tan(u1))); + F[1] = (-(tanh(u2))); + F[2] = (-(asin(u3))); + F[3] = (acos(u4)-1.000000e+00); + F[4] = (-(atan(u5))); + F[5] = (-(asinh(u6))); + F[6] = (1.000000e+00-acosh(u7)); + F[7] = (-(atanh(u8))); +} /* eval */ +void calc_jac(double S[equa], double tk, double R[equa], double Jac[equa+1][equa+1]) +{ + double u1; + double u2; + double u3; + double u4; + double u5; + double u6; + double u7; + double u8; + u1=S[0]; + u2=S[1]; + u3=S[2]; + u4=S[3]; + u5=S[4]; + u6=S[5]; + u7=S[6]; + u8=S[7]; +Jac[1][1]=tk*((-((1.000000e+00/(cos(u1)*cos(u1))))))-(1+4*R[0]); +Jac[1][2]=tk*(-0.000000e+00); +Jac[1][3]=tk*(-0.000000e+00); +Jac[1][4]=tk*(-0.000000e+00); +Jac[1][5]=tk*(-0.000000e+00); +Jac[1][6]=tk*(-0.000000e+00); +Jac[1][7]=tk*(-0.000000e+00); +Jac[1][8]=tk*(-0.000000e+00); +Jac[2][1]=tk*(-0.000000e+00); +Jac[2][2]=tk*((-((1.000000e+00/(cosh(u2)*cosh(u2))))))-(1+4*R[1]); +Jac[2][3]=tk*(-0.000000e+00); +Jac[2][4]=tk*(-0.000000e+00); +Jac[2][5]=tk*(-0.000000e+00); +Jac[2][6]=tk*(-0.000000e+00); +Jac[2][7]=tk*(-0.000000e+00); +Jac[2][8]=tk*(-0.000000e+00); +Jac[3][1]=tk*(-0.000000e+00); +Jac[3][2]=tk*(-0.000000e+00); +Jac[3][3]=tk*((-((1.000000e+00/(pow((1.000000e+00-(u3*u3)), +5.000000e-01))))))-(1+4*R[2]); +Jac[3][4]=tk*(-0.000000e+00); +Jac[3][5]=tk*(-0.000000e+00); +Jac[3][6]=tk*(-0.000000e+00); +Jac[3][7]=tk*(-0.000000e+00); +Jac[3][8]=tk*(-0.000000e+00); +Jac[4][1]=tk*(0.000000e+00); +Jac[4][2]=tk*(0.000000e+00); +Jac[4][3]=tk*(0.000000e+00); +Jac[4][4]=tk*((-1.000000e+00/(pow((1.000000e+00-(u4*u4)),5.000000e-01 +))))-(1+4*R[3]); +Jac[4][5]=tk*(0.000000e+00); +Jac[4][6]=tk*(0.000000e+00); +Jac[4][7]=tk*(0.000000e+00); +Jac[4][8]=tk*(0.000000e+00); +Jac[5][1]=tk*(-0.000000e+00); +Jac[5][2]=tk*(-0.000000e+00); +Jac[5][3]=tk*(-0.000000e+00); +Jac[5][4]=tk*(-0.000000e+00); +Jac[5][5]=tk*((-((1.000000e+00/(1.000000e+00+(u5*u5))))))-(1+4*R[4]); +Jac[5][6]=tk*(-0.000000e+00); +Jac[5][7]=tk*(-0.000000e+00); +Jac[5][8]=tk*(-0.000000e+00); +Jac[6][1]=tk*(-0.000000e+00); +Jac[6][2]=tk*(-0.000000e+00); +Jac[6][3]=tk*(-0.000000e+00); +Jac[6][4]=tk*(-0.000000e+00); +Jac[6][5]=tk*(-0.000000e+00); +Jac[6][6]=tk*((-((1.000000e+00/(pow(((u6*u6)+1.000000e+00), +5.000000e-01))))))-(1+4*R[5]); +Jac[6][7]=tk*(-0.000000e+00); +Jac[6][8]=tk*(-0.000000e+00); +Jac[7][1]=tk*(0.000000e+00); +Jac[7][2]=tk*(0.000000e+00); +Jac[7][3]=tk*(0.000000e+00); +Jac[7][4]=tk*(0.000000e+00); +Jac[7][5]=tk*(0.000000e+00); +Jac[7][6]=tk*(0.000000e+00); +Jac[7][7]=tk*((-((1.000000e+00/(pow(((u7*u7)-1.000000e+00), +5.000000e-01))))))-(1+4*R[6]); +Jac[7][8]=tk*(0.000000e+00); +Jac[8][1]=tk*(-0.000000e+00); +Jac[8][2]=tk*(-0.000000e+00); +Jac[8][3]=tk*(-0.000000e+00); +Jac[8][4]=tk*(-0.000000e+00); +Jac[8][5]=tk*(-0.000000e+00); +Jac[8][6]=tk*(-0.000000e+00); +Jac[8][7]=tk*(-0.000000e+00); +Jac[8][8]=tk*((-((1.000000e+00/(1.000000e+00-(u8*u8))))))-(1+4*R[7]); +} +double reac_F(double S[equa], double K[equa], double R[equa], double tk, int l) { + double u1; + double u2; + double u3; + double u4; + double u5; + double u6; + double u7; + double u8; + u1=S[0]; + u2=S[1]; + u3=S[2]; + u4=S[3]; + u5=S[4]; + u6=S[5]; + u7=S[6]; + u8=S[7]; +switch (l) { +case 1: +return (tk*((-(tan(u1))))-S[0]*(1+4*R[0])+K[0]); +break; +case 2: +return (tk*((-(tanh(u2))))-S[1]*(1+4*R[1])+K[1]); +break; +case 3: +return (tk*((-(asin(u3))))-S[2]*(1+4*R[2])+K[2]); +break; +case 4: +return (tk*((acos(u4)-1.000000e+00))-S[3]*(1+4*R[3])+K[3]); +break; +case 5: +return (tk*((-(atan(u5))))-S[4]*(1+4*R[4])+K[4]); +break; +case 6: +return (tk*((-(asinh(u6))))-S[5]*(1+4*R[5])+K[5]); +break; +case 7: +return (tk*((1.000000e+00-acosh(u7)))-S[6]*(1+4*R[6])+K[6]); +break; +case 8: +return (tk*((-(atanh(u8))))-S[7]*(1+4*R[7])+K[7]); +break; +} +} +void calc_jac2(double S[equa], double Jac[equa][equa]) +{ +double u1; +double u2; +double u3; +double u4; +double u5; +double u6; +double u7; +double u8; +u1=S[0]; +u2=S[1]; +u3=S[2]; +u4=S[3]; +u5=S[4]; +u6=S[5]; +u7=S[6]; +u8=S[7]; +Jac[0][0]=(-((1.000000e+00/(cos(u1)*cos(u1))))); +Jac[0][1]=-0.000000e+00; +Jac[0][2]=-0.000000e+00; +Jac[0][3]=-0.000000e+00; +Jac[0][4]=-0.000000e+00; +Jac[0][5]=-0.000000e+00; +Jac[0][6]=-0.000000e+00; +Jac[0][7]=-0.000000e+00; +Jac[1][0]=-0.000000e+00; +Jac[1][1]=(-((1.000000e+00/(cosh(u2)*cosh(u2))))); +Jac[1][2]=-0.000000e+00; +Jac[1][3]=-0.000000e+00; +Jac[1][4]=-0.000000e+00; +Jac[1][5]=-0.000000e+00; +Jac[1][6]=-0.000000e+00; +Jac[1][7]=-0.000000e+00; +Jac[2][0]=-0.000000e+00; +Jac[2][1]=-0.000000e+00; +Jac[2][2]=(-((1.000000e+00/(pow((1.000000e+00-(u3*u3)), +5.000000e-01))))); +Jac[2][3]=-0.000000e+00; +Jac[2][4]=-0.000000e+00; +Jac[2][5]=-0.000000e+00; +Jac[2][6]=-0.000000e+00; +Jac[2][7]=-0.000000e+00; +Jac[3][0]=0.000000e+00; +Jac[3][1]=0.000000e+00; +Jac[3][2]=0.000000e+00; +Jac[3][3]=(-1.000000e+00/(pow((1.000000e+00-(u4*u4)),5.000000e-01 +))); +Jac[3][4]=0.000000e+00; +Jac[3][5]=0.000000e+00; +Jac[3][6]=0.000000e+00; +Jac[3][7]=0.000000e+00; +Jac[4][0]=-0.000000e+00; +Jac[4][1]=-0.000000e+00; +Jac[4][2]=-0.000000e+00; +Jac[4][3]=-0.000000e+00; +Jac[4][4]=(-((1.000000e+00/(1.000000e+00+(u5*u5))))); +Jac[4][5]=-0.000000e+00; +Jac[4][6]=-0.000000e+00; +Jac[4][7]=-0.000000e+00; +Jac[5][0]=-0.000000e+00; +Jac[5][1]=-0.000000e+00; +Jac[5][2]=-0.000000e+00; +Jac[5][3]=-0.000000e+00; +Jac[5][4]=-0.000000e+00; +Jac[5][5]=(-((1.000000e+00/(pow(((u6*u6)+1.000000e+00), +5.000000e-01))))); +Jac[5][6]=-0.000000e+00; +Jac[5][7]=-0.000000e+00; +Jac[6][0]=0.000000e+00; +Jac[6][1]=0.000000e+00; +Jac[6][2]=0.000000e+00; +Jac[6][3]=0.000000e+00; +Jac[6][4]=0.000000e+00; +Jac[6][5]=0.000000e+00; +Jac[6][6]=(-((1.000000e+00/(pow(((u7*u7)-1.000000e+00), +5.000000e-01))))); +Jac[6][7]=0.000000e+00; +Jac[7][0]=-0.000000e+00; +Jac[7][1]=-0.000000e+00; +Jac[7][2]=-0.000000e+00; +Jac[7][3]=-0.000000e+00; +Jac[7][4]=-0.000000e+00; +Jac[7][5]=-0.000000e+00; +Jac[7][6]=-0.000000e+00; +Jac[7][7]=(-((1.000000e+00/(1.000000e+00-(u8*u8))))); +} diff --git a/test/expected/derivatives2.des.m2/model.h b/test/expected/derivatives2.des.m2/model.h new file mode 100644 index 0000000..220879c --- /dev/null +++ b/test/expected/derivatives2.des.m2/model.h @@ -0,0 +1,14 @@ +/* ######################## +*/ + +#define n_grids 0 +#define m_grids 0 +#define equa 8 + +extern void init_diff_const(void); +double D[equa]; +extern double reac(double*, int); +extern void eval(double *, double *); +void calc_jac(double S[equa], double tk, double R[equa], double Jac[equa+1][equa+1]); +extern double reac_F(double S[equa], double K[equa], double R[equa], double tk, int l); +void calc_jac2(double S[equa], double Jac[equa][equa]); diff --git a/test/expected/derivatives2.des.m2/stderr b/test/expected/derivatives2.des.m2/stderr new file mode 100644 index 0000000..6d491b9 --- /dev/null +++ b/test/expected/derivatives2.des.m2/stderr @@ -0,0 +1,2 @@ +ERROR: The constant ngrid is not defined! +ERROR: The constant mgrid is not defined! diff --git a/test/expected/derivatives2.des.m2/stdout b/test/expected/derivatives2.des.m2/stdout new file mode 100644 index 0000000..d0e10e1 --- /dev/null +++ b/test/expected/derivatives2.des.m2/stdout @@ -0,0 +1,12 @@ +kc v1.10, (C) Copyright by Kenneth Geisshirt and Keld Nielsen, 1992-1996 +Species used (*=dyn. var.): + *u1 + *u2 + *u3 + *u4 + *u5 + *u6 + *u7 + *u8 +Constants declared: + etime = 1.000000e+00 diff --git a/test/expected/derivatives2.des.m3/model.c b/test/expected/derivatives2.des.m3/model.c new file mode 100644 index 0000000..dff29fd --- /dev/null +++ b/test/expected/derivatives2.des.m3/model.c @@ -0,0 +1,167 @@ +/********************************************* + WARNING: This file was generated by kc v1.10 + CopyWrong by Kenneth Geisshirt + ######################## +**********************************************/ +#include "model.h" +#include +#include +void reac(double* S_, double* v_) { +int j_; +double u1; +double u2; +double u3; +double u4; +double u5; +double u6; +double u7; +double u8; +u1=S_[0]; +u2=S_[1]; +u3=S_[2]; +u4=S_[3]; +u5=S_[4]; +u6=S_[5]; +u7=S_[6]; +u8=S_[7]; +v_[0]=((-(tan(u1)))); +v_[1]=((-(tanh(u2)))); +v_[2]=((-(asin(u3)))); +v_[3]=((acos(u4)-1.000000e+00)); +v_[4]=((-(atan(u5)))); +v_[5]=((-(asinh(u6)))); +v_[6]=((1.000000e+00-acosh(u7))); +v_[7]=((-(atanh(u8)))); +} +void jacobi(double *S_){ +int j_; +double u1; +double u2; +double u3; +double u4; +double u5; +double u6; +double u7; +double u8; +u1=S_[0]; +u2=S_[1]; +u3=S_[2]; +u4=S_[3]; +u5=S_[4]; +u6=S_[5]; +u7=S_[6]; +u8=S_[7]; +jacobi_matx[0][0]=(-((1.000000e+00/(cos(u1)*cos(u1))))); +jacobi_matx[1][1]=(-((1.000000e+00/(cosh(u2)*cosh(u2))))); +jacobi_matx[2][2]=(-((1.000000e+00/(pow((1.000000e+00-(u3*u3)), +5.000000e-01))))); +jacobi_matx[3][3]=(-1.000000e+00/(pow((1.000000e+00-(u4*u4)),5.000000e-01 +))); +jacobi_matx[4][4]=(-((1.000000e+00/(1.000000e+00+(u5*u5))))); +jacobi_matx[5][5]=(-((1.000000e+00/(pow(((u6*u6)+1.000000e+00), +5.000000e-01))))); +jacobi_matx[6][6]=(-((1.000000e+00/(pow(((u7*u7)-1.000000e+00), +5.000000e-01))))); +jacobi_matx[7][7]=(-((1.000000e+00/(1.000000e+00-(u8*u8))))); +} +void InitValues(void) { +FILE *infile_; +x_[0]=5.000000e-01; +do_print[0]=1; +x_[1]=5.000000e-01; +do_print[1]=1; +x_[2]=5.000000e-01; +do_print[2]=1; +x_[3]=5.000000e-01; +do_print[3]=1; +x_[4]=5.000000e-01; +do_print[4]=1; +x_[5]=5.000000e-01; +do_print[5]=1; +x_[6]=2.000000e+00; +do_print[6]=1; +x_[7]=5.000000e-01; +do_print[7]=1; +epsmin_=0.000000e+00; +dtime_=2.000000e+00; +prnmode_=0; +etime_=1.000000e+00; +stime_=0.000000e+00; +htime_=1.000000e+00; +epsr_=1.000000e-05; +epsa_=1.000000e-10; +epse_=1.000000e-10; +solver_=1; +step_adjustment_factor=9.000000e-01; +steplimit_increase=1.500000e+00; +steplimit_decrease=5.000000e-01; +htimemin_=1.000000e-20; +begin_print=0.000000e+00; +scaling_=0; +debug_=1; +(void) strcpy(species[0], "u1"); +(void) strcpy(species[1], "u2"); +(void) strcpy(species[2], "u3"); +(void) strcpy(species[3], "u4"); +(void) strcpy(species[4], "u5"); +(void) strcpy(species[5], "u6"); +(void) strcpy(species[6], "u7"); +(void) strcpy(species[7], "u8"); +(void) strcpy(datafilename_,"kinwrkda"); +jacobi_matx[0][1]=-0.000000e+00; +jacobi_matx[0][2]=-0.000000e+00; +jacobi_matx[0][3]=-0.000000e+00; +jacobi_matx[0][4]=-0.000000e+00; +jacobi_matx[0][5]=-0.000000e+00; +jacobi_matx[0][6]=-0.000000e+00; +jacobi_matx[0][7]=-0.000000e+00; +jacobi_matx[1][0]=-0.000000e+00; +jacobi_matx[1][2]=-0.000000e+00; +jacobi_matx[1][3]=-0.000000e+00; +jacobi_matx[1][4]=-0.000000e+00; +jacobi_matx[1][5]=-0.000000e+00; +jacobi_matx[1][6]=-0.000000e+00; +jacobi_matx[1][7]=-0.000000e+00; +jacobi_matx[2][0]=-0.000000e+00; +jacobi_matx[2][1]=-0.000000e+00; +jacobi_matx[2][3]=-0.000000e+00; +jacobi_matx[2][4]=-0.000000e+00; +jacobi_matx[2][5]=-0.000000e+00; +jacobi_matx[2][6]=-0.000000e+00; +jacobi_matx[2][7]=-0.000000e+00; +jacobi_matx[3][0]=0.000000e+00; +jacobi_matx[3][1]=0.000000e+00; +jacobi_matx[3][2]=0.000000e+00; +jacobi_matx[3][4]=0.000000e+00; +jacobi_matx[3][5]=0.000000e+00; +jacobi_matx[3][6]=0.000000e+00; +jacobi_matx[3][7]=0.000000e+00; +jacobi_matx[4][0]=-0.000000e+00; +jacobi_matx[4][1]=-0.000000e+00; +jacobi_matx[4][2]=-0.000000e+00; +jacobi_matx[4][3]=-0.000000e+00; +jacobi_matx[4][5]=-0.000000e+00; +jacobi_matx[4][6]=-0.000000e+00; +jacobi_matx[4][7]=-0.000000e+00; +jacobi_matx[5][0]=-0.000000e+00; +jacobi_matx[5][1]=-0.000000e+00; +jacobi_matx[5][2]=-0.000000e+00; +jacobi_matx[5][3]=-0.000000e+00; +jacobi_matx[5][4]=-0.000000e+00; +jacobi_matx[5][6]=-0.000000e+00; +jacobi_matx[5][7]=-0.000000e+00; +jacobi_matx[6][0]=0.000000e+00; +jacobi_matx[6][1]=0.000000e+00; +jacobi_matx[6][2]=0.000000e+00; +jacobi_matx[6][3]=0.000000e+00; +jacobi_matx[6][4]=0.000000e+00; +jacobi_matx[6][5]=0.000000e+00; +jacobi_matx[6][7]=0.000000e+00; +jacobi_matx[7][0]=-0.000000e+00; +jacobi_matx[7][1]=-0.000000e+00; +jacobi_matx[7][2]=-0.000000e+00; +jacobi_matx[7][3]=-0.000000e+00; +jacobi_matx[7][4]=-0.000000e+00; +jacobi_matx[7][5]=-0.000000e+00; +jacobi_matx[7][6]=-0.000000e+00; +} diff --git a/test/expected/derivatives2.des.m3/model.h b/test/expected/derivatives2.des.m3/model.h new file mode 100644 index 0000000..89a5bbf --- /dev/null +++ b/test/expected/derivatives2.des.m3/model.h @@ -0,0 +1,17 @@ +/********************************************* + WARNING: This file was generated by kc v1.10 + CopyWrong by Kenneth Geisshirt + ######################## +**********************************************/ +#ifndef _MODEL_HEADER_ +#define _MODEL_HEADER_ +#define equa 8 +#undef _DO_PERT_ +#undef PRINT_ON_SCREEN +double x_[equa],x_pert[equa],xscal_[equa]; +int do_print[equa]; +char species[equa][25]; +extern void reac(double *, double *); +extern void jacobi(double *); +extern void InitValues(void); +#endif diff --git a/test/expected/derivatives2.des.m3/sim.last b/test/expected/derivatives2.des.m3/sim.last new file mode 100644 index 0000000..3c18dbc --- /dev/null +++ b/test/expected/derivatives2.des.m3/sim.last @@ -0,0 +1 @@ +1.000000e+00 1.772867e-01 1.905337e-01 1.804815e-01 5.278953e-01 1.903610e-01 1.871285e-01 1.763190e+00 1.770787e-01 diff --git a/test/expected/derivatives2.des.m3/stderr b/test/expected/derivatives2.des.m3/stderr new file mode 100644 index 0000000..e69de29 diff --git a/test/expected/derivatives2.des.m3/stdout b/test/expected/derivatives2.des.m3/stdout new file mode 100644 index 0000000..d0e10e1 --- /dev/null +++ b/test/expected/derivatives2.des.m3/stdout @@ -0,0 +1,12 @@ +kc v1.10, (C) Copyright by Kenneth Geisshirt and Keld Nielsen, 1992-1996 +Species used (*=dyn. var.): + *u1 + *u2 + *u3 + *u4 + *u5 + *u6 + *u7 + *u8 +Constants declared: + etime = 1.000000e+00 diff --git a/test/expected/derivatives2.des.m4/model.f b/test/expected/derivatives2.des.m4/model.f new file mode 100644 index 0000000..e69de29 diff --git a/test/expected/derivatives2.des.m4/stderr b/test/expected/derivatives2.des.m4/stderr new file mode 100644 index 0000000..68a037d --- /dev/null +++ b/test/expected/derivatives2.des.m4/stderr @@ -0,0 +1 @@ +Continuation program aborted: Wrong number of parameters - should be between 2 and 40. diff --git a/test/expected/derivatives2.des.m4/stdout b/test/expected/derivatives2.des.m4/stdout new file mode 100644 index 0000000..d0e10e1 --- /dev/null +++ b/test/expected/derivatives2.des.m4/stdout @@ -0,0 +1,12 @@ +kc v1.10, (C) Copyright by Kenneth Geisshirt and Keld Nielsen, 1992-1996 +Species used (*=dyn. var.): + *u1 + *u2 + *u3 + *u4 + *u5 + *u6 + *u7 + *u8 +Constants declared: + etime = 1.000000e+00 diff --git a/test/expected/derivatives2.des.m5/kcm5const.p b/test/expected/derivatives2.des.m5/kcm5const.p new file mode 100644 index 0000000..e69de29 diff --git a/test/expected/derivatives2.des.m5/kcm5proc.p b/test/expected/derivatives2.des.m5/kcm5proc.p new file mode 100644 index 0000000..e69de29 diff --git a/test/expected/derivatives2.des.m5/stderr b/test/expected/derivatives2.des.m5/stderr new file mode 100644 index 0000000..159afbd --- /dev/null +++ b/test/expected/derivatives2.des.m5/stderr @@ -0,0 +1 @@ +KNCont: Wrong number of parameters - should be either 1 or 2. diff --git a/test/expected/derivatives2.des.m5/stdout b/test/expected/derivatives2.des.m5/stdout new file mode 100644 index 0000000..d0e10e1 --- /dev/null +++ b/test/expected/derivatives2.des.m5/stdout @@ -0,0 +1,12 @@ +kc v1.10, (C) Copyright by Kenneth Geisshirt and Keld Nielsen, 1992-1996 +Species used (*=dyn. var.): + *u1 + *u2 + *u3 + *u4 + *u5 + *u6 + *u7 + *u8 +Constants declared: + etime = 1.000000e+00 From e4e55428b21e65e27efd7a2f0e8ab54206223a2f Mon Sep 17 00:00:00 2001 From: Kenneth Geisshirt Date: Sat, 31 Oct 2026 18:52:55 +0100 Subject: [PATCH 05/13] Evaluate asinh, acosh and atanh TreeEval returned the argument unchanged for these functions; the calls were commented out because C89 had no asinh, acosh and atanh. C99 does, so constants such as asinh(1.0) are now evaluated. derivatives2 declares one constant per function to test this. Co-Authored-By: Claude Opus 5.5 --- src/symbmath.c | 6 +++--- test/derivatives2.des | 3 +++ test/expected/derivatives2.des.m1/stdout | 3 +++ test/expected/derivatives2.des.m2/stdout | 3 +++ test/expected/derivatives2.des.m3/stdout | 3 +++ test/expected/derivatives2.des.m4/stdout | 3 +++ test/expected/derivatives2.des.m5/stdout | 3 +++ 7 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/symbmath.c b/src/symbmath.c index 757a49d..6468210 100644 --- a/src/symbmath.c +++ b/src/symbmath.c @@ -936,13 +936,13 @@ double TreeEval(Tree t) { res=atan(res); break; case Asinh: - /* res=asinh(res); */ + res=asinh(res); break; case Acosh: - /* res=acosh(res); */ + res=acosh(res); break; case Atanh: - /* res=atanh(res); */ + res=atanh(res); break; } /* switch */ } /* if */ diff --git a/test/derivatives2.des b/test/derivatives2.des index 4cfaa88..68f2d25 100644 --- a/test/derivatives2.des +++ b/test/derivatives2.des @@ -1,4 +1,7 @@ etime = 1.0; +c1 = asinh(1.0); +c2 = acosh(2.0); +c3 = atanh(0.5); u1' = -tan(u1); u2' = -tanh(u2); diff --git a/test/expected/derivatives2.des.m1/stdout b/test/expected/derivatives2.des.m1/stdout index 292d344..c6d9f49 100644 --- a/test/expected/derivatives2.des.m1/stdout +++ b/test/expected/derivatives2.des.m1/stdout @@ -10,6 +10,9 @@ Species used (*=dyn. var.): *u8 Constants declared: etime = 1.000000e+00 + c1 = 8.813736e-01 + c2 = 1.316958e+00 + c3 = 5.493061e-01 The Jacobian matrix is: J(1, 1) = -1.29844641040952e+00 J(1, 2) = -0.00000000000000e+00 diff --git a/test/expected/derivatives2.des.m2/stdout b/test/expected/derivatives2.des.m2/stdout index d0e10e1..df13a52 100644 --- a/test/expected/derivatives2.des.m2/stdout +++ b/test/expected/derivatives2.des.m2/stdout @@ -10,3 +10,6 @@ Species used (*=dyn. var.): *u8 Constants declared: etime = 1.000000e+00 + c1 = 8.813736e-01 + c2 = 1.316958e+00 + c3 = 5.493061e-01 diff --git a/test/expected/derivatives2.des.m3/stdout b/test/expected/derivatives2.des.m3/stdout index d0e10e1..df13a52 100644 --- a/test/expected/derivatives2.des.m3/stdout +++ b/test/expected/derivatives2.des.m3/stdout @@ -10,3 +10,6 @@ Species used (*=dyn. var.): *u8 Constants declared: etime = 1.000000e+00 + c1 = 8.813736e-01 + c2 = 1.316958e+00 + c3 = 5.493061e-01 diff --git a/test/expected/derivatives2.des.m4/stdout b/test/expected/derivatives2.des.m4/stdout index d0e10e1..df13a52 100644 --- a/test/expected/derivatives2.des.m4/stdout +++ b/test/expected/derivatives2.des.m4/stdout @@ -10,3 +10,6 @@ Species used (*=dyn. var.): *u8 Constants declared: etime = 1.000000e+00 + c1 = 8.813736e-01 + c2 = 1.316958e+00 + c3 = 5.493061e-01 diff --git a/test/expected/derivatives2.des.m5/stdout b/test/expected/derivatives2.des.m5/stdout index d0e10e1..df13a52 100644 --- a/test/expected/derivatives2.des.m5/stdout +++ b/test/expected/derivatives2.des.m5/stdout @@ -10,3 +10,6 @@ Species used (*=dyn. var.): *u8 Constants declared: etime = 1.000000e+00 + c1 = 8.813736e-01 + c2 = 1.316958e+00 + c3 = 5.493061e-01 From 1d6be725d9918ee756d227f9f3c3854c37ce64f2 Mon Sep 17 00:00:00 2001 From: Kenneth Geisshirt Date: Sat, 31 Oct 2026 18:56:17 +0100 Subject: [PATCH 06/13] Fix the sign of reduced sums with a negated term TreeReduce rewrote f+(-g) as f-(-g) and f-(-g) as f+(-g): it kept the negation node instead of its operand. Each reduction flipped the sign of g, and expressions are reduced again on every operation, so the result depended on how often a subtree was reduced. Affected are models where a negated term ends up on the right of a sum, e.g. through a reversible reaction. In gtf and shn90 single Jacobian entries had the wrong value (shn90 Jac[3][3] in mode 2: +0.0999 instead of -0.540), which changes their mode 1 eigenvalues and mode 3 end states. The changed entries were checked against finite differences of the generated right-hand sides. In the other models only the printed form changes, e.g. x+(-(y)) is now x-y. Co-Authored-By: Claude Opus 5.5 --- src/symbmath.c | 4 +- test/expected/burst-2par.des.m2/model.c | 4 +- test/expected/burst-2par.des.m3/model.c | 2 +- test/expected/burst-2par.des.m4/model.f | 2 +- test/expected/burst-2par.des.m5/kcm5proc.p | 2 +- test/expected/burst.des.m2/model.c | 4 +- test/expected/burst.des.m3/model.c | 2 +- test/expected/burst.des.m4/model.f | 2 +- test/expected/burst.des.m5/kcm5proc.p | 2 +- test/expected/burst.kcd.m2/model.c | 16 +- test/expected/burst.kcd.m3/model.c | 8 +- test/expected/burst3.13.m2/model.c | 4 +- test/expected/burst3.13.m3/model.c | 2 +- test/expected/burst3.des.m2/model.c | 4 +- test/expected/burst3.des.m3/model.c | 2 +- test/expected/burst3.des.m4/model.f | 2 +- test/expected/burst3.des.m5/kcm5proc.p | 2 +- test/expected/gtf.des.m1/stdout | 998 ++++++++++----------- test/expected/gtf.des.m2/model.c | 128 +-- test/expected/gtf.des.m3/model.c | 64 +- test/expected/gtf.des.m3/sim.last | 2 +- test/expected/hbry1.des.m2/model.c | 24 +- test/expected/hbry1.des.m3/model.c | 12 +- test/expected/hbry1.des.m3/sim.last | 2 +- test/expected/real.des.m2/model.c | 28 +- test/expected/real.des.m3/model.c | 14 +- test/expected/shn90.des.m1/stdout | 98 +- test/expected/shn90.des.m2/model.c | 24 +- test/expected/shn90.des.m3/model.c | 12 +- test/expected/shn90.des.m3/sim.last | 2 +- 30 files changed, 736 insertions(+), 736 deletions(-) diff --git a/src/symbmath.c b/src/symbmath.c index 6468210..3084cd6 100644 --- a/src/symbmath.c +++ b/src/symbmath.c @@ -83,7 +83,7 @@ void TreeReduce(Tree tin) { res->data.oper.left=TreeCreate(); TreeCpy(res->data.oper.left, t->data.oper.left); res->data.oper.right=TreeCreate(); - TreeCpy(res->data.oper.right, t->data.oper.right); + TreeCpy(res->data.oper.right, t->data.oper.right->data.right); } /* if */ break; case Sub: @@ -125,7 +125,7 @@ void TreeReduce(Tree tin) { res->data.oper.left=TreeCreate(); TreeCpy(res->data.oper.left, t->data.oper.left); res->data.oper.right=TreeCreate(); - TreeCpy(res->data.oper.right, t->data.oper.right); + TreeCpy(res->data.oper.right, t->data.oper.right->data.right); } /* if */ /* (-f-g) -> -(f+g) */ diff --git a/test/expected/burst-2par.des.m2/model.c b/test/expected/burst-2par.des.m2/model.c index e933a07..0a25ba6 100644 --- a/test/expected/burst-2par.des.m2/model.c +++ b/test/expected/burst-2par.des.m2/model.c @@ -151,7 +151,7 @@ void calc_jac(double S[equa], double tk, double R[equa], double Jac[equa+1][equa CeIII=(8.600000e-05-CeIV); MA=1.670000e-01; Jac[1][1]=tk*((((((-1.000000e+00*j0)+(-1.000000e+00*(2.000000e+06 -*Br_m)))+-3.960000e-01)+(-((7.000000e+03*CeIV))))+(-2.000000e+00 +*Br_m)))+-3.960000e-01)-(7.000000e+03*CeIV))+(-2.000000e+00 *(3.000000e+03*(HBrO2*2.000000e+00)))))-(1+4*R[0]); Jac[1][2]=tk*((2.400000e-02+(-1.000000e+00*(2.000000e+06 *HBrO2)))); @@ -294,7 +294,7 @@ BrMA=S[5]; CeIII=(8.600000e-05-CeIV); MA=1.670000e-01; Jac[0][0]=(((((-1.000000e+00*j0)+(-1.000000e+00*(2.000000e+06 -*Br_m)))+-3.960000e-01)+(-((7.000000e+03*CeIV))))+(-2.000000e+00 +*Br_m)))+-3.960000e-01)-(7.000000e+03*CeIV))+(-2.000000e+00 *(3.000000e+03*(HBrO2*2.000000e+00)))); Jac[0][1]=(2.400000e-02+(-1.000000e+00*(2.000000e+06 *HBrO2))); diff --git a/test/expected/burst-2par.des.m3/model.c b/test/expected/burst-2par.des.m3/model.c index 5310141..082c3bb 100644 --- a/test/expected/burst-2par.des.m3/model.c +++ b/test/expected/burst-2par.des.m3/model.c @@ -59,7 +59,7 @@ HBrO=S_[3]; BrO2=S_[4]; BrMA=S_[5]; jacobi_matx[0][0]=(((((-1.000000e+00*j0)+(-1.000000e+00*(2.000000e+06 -*Br_m)))+-3.960000e-01)+(-((7.000000e+03*CeIV))))+(-2.000000e+00 +*Br_m)))+-3.960000e-01)-(7.000000e+03*CeIV))+(-2.000000e+00 *(3.000000e+03*(HBrO2*2.000000e+00)))); jacobi_matx[0][1]=(2.400000e-02+(-1.000000e+00*(2.000000e+06 *HBrO2))); diff --git a/test/expected/burst-2par.des.m4/model.f b/test/expected/burst-2par.des.m4/model.f index 3b5d7e8..dc37a25 100644 --- a/test/expected/burst-2par.des.m4/model.f +++ b/test/expected/burst-2par.des.m4/model.f @@ -63,7 +63,7 @@ subroutine model(ndim,nvar,n,tvar,xvar,fvar,gvar) &))+((-1.000000e+00)*(((3.000000e+01)*CeIV)*BrMA))) gvar(1,1) = ((((((-1.000000e+00)*j0)+((-1.000000e+00)*((2.000000e+06) - &*Br_m)))+(-3.960000e-01))+(-(((7.000000e+03)*CeIV))))+((-2.000000e+00) + &*Br_m)))+(-3.960000e-01))-((7.000000e+03)*CeIV))+((-2.000000e+00) &*((3.000000e+03)*(HBrO2*(2.000000e+00))))) gvar(1,2) = ((2.400000e-02)+((-1.000000e+00)*((2.000000e+06) &*HBrO2))) diff --git a/test/expected/burst-2par.des.m5/kcm5proc.p b/test/expected/burst-2par.des.m5/kcm5proc.p index 1595b42..27c98c8 100644 --- a/test/expected/burst-2par.des.m5/kcm5proc.p +++ b/test/expected/burst-2par.des.m5/kcm5proc.p @@ -268,7 +268,7 @@ vv_[6]:=((((-1)*(j0*BrMA))+((kf6*HBrO)*(1.670000e-01)))+ ((-1)*(((30)*CeIV)*BrMA))); IF bj_ THEN BEGIN jj_[1, 1]:=((((((-1)*j0)+((-1)*((2000000)*Br_m)))+(-3.960000e-01) -)+(-(((7000)*CeIV))))+((-2)*((3000)*(HBrO2*(2))))); +)-((7000)*CeIV))+((-2)*((3000)*(HBrO2*(2))))); jj_[1, 2]:=((2.400000e-02)+((-1)*((2000000)*HBrO2))); jj_[1, 3]:=((((62000)*BrO2)*(-1))-((7000)*HBrO2)); jj_[1, 5]:=(((-1)*(-((((700000)*(BrO2*(2)))*(5.550000e+01))))) diff --git a/test/expected/burst.des.m2/model.c b/test/expected/burst.des.m2/model.c index e933a07..0a25ba6 100644 --- a/test/expected/burst.des.m2/model.c +++ b/test/expected/burst.des.m2/model.c @@ -151,7 +151,7 @@ void calc_jac(double S[equa], double tk, double R[equa], double Jac[equa+1][equa CeIII=(8.600000e-05-CeIV); MA=1.670000e-01; Jac[1][1]=tk*((((((-1.000000e+00*j0)+(-1.000000e+00*(2.000000e+06 -*Br_m)))+-3.960000e-01)+(-((7.000000e+03*CeIV))))+(-2.000000e+00 +*Br_m)))+-3.960000e-01)-(7.000000e+03*CeIV))+(-2.000000e+00 *(3.000000e+03*(HBrO2*2.000000e+00)))))-(1+4*R[0]); Jac[1][2]=tk*((2.400000e-02+(-1.000000e+00*(2.000000e+06 *HBrO2)))); @@ -294,7 +294,7 @@ BrMA=S[5]; CeIII=(8.600000e-05-CeIV); MA=1.670000e-01; Jac[0][0]=(((((-1.000000e+00*j0)+(-1.000000e+00*(2.000000e+06 -*Br_m)))+-3.960000e-01)+(-((7.000000e+03*CeIV))))+(-2.000000e+00 +*Br_m)))+-3.960000e-01)-(7.000000e+03*CeIV))+(-2.000000e+00 *(3.000000e+03*(HBrO2*2.000000e+00)))); Jac[0][1]=(2.400000e-02+(-1.000000e+00*(2.000000e+06 *HBrO2))); diff --git a/test/expected/burst.des.m3/model.c b/test/expected/burst.des.m3/model.c index 5310141..082c3bb 100644 --- a/test/expected/burst.des.m3/model.c +++ b/test/expected/burst.des.m3/model.c @@ -59,7 +59,7 @@ HBrO=S_[3]; BrO2=S_[4]; BrMA=S_[5]; jacobi_matx[0][0]=(((((-1.000000e+00*j0)+(-1.000000e+00*(2.000000e+06 -*Br_m)))+-3.960000e-01)+(-((7.000000e+03*CeIV))))+(-2.000000e+00 +*Br_m)))+-3.960000e-01)-(7.000000e+03*CeIV))+(-2.000000e+00 *(3.000000e+03*(HBrO2*2.000000e+00)))); jacobi_matx[0][1]=(2.400000e-02+(-1.000000e+00*(2.000000e+06 *HBrO2))); diff --git a/test/expected/burst.des.m4/model.f b/test/expected/burst.des.m4/model.f index 3b5d7e8..dc37a25 100644 --- a/test/expected/burst.des.m4/model.f +++ b/test/expected/burst.des.m4/model.f @@ -63,7 +63,7 @@ subroutine model(ndim,nvar,n,tvar,xvar,fvar,gvar) &))+((-1.000000e+00)*(((3.000000e+01)*CeIV)*BrMA))) gvar(1,1) = ((((((-1.000000e+00)*j0)+((-1.000000e+00)*((2.000000e+06) - &*Br_m)))+(-3.960000e-01))+(-(((7.000000e+03)*CeIV))))+((-2.000000e+00) + &*Br_m)))+(-3.960000e-01))-((7.000000e+03)*CeIV))+((-2.000000e+00) &*((3.000000e+03)*(HBrO2*(2.000000e+00))))) gvar(1,2) = ((2.400000e-02)+((-1.000000e+00)*((2.000000e+06) &*HBrO2))) diff --git a/test/expected/burst.des.m5/kcm5proc.p b/test/expected/burst.des.m5/kcm5proc.p index 838ce55..93035af 100644 --- a/test/expected/burst.des.m5/kcm5proc.p +++ b/test/expected/burst.des.m5/kcm5proc.p @@ -268,7 +268,7 @@ vv_[6]:=((((-1)*(j0*BrMA))+((kf6*HBrO)*(1.670000e-01)))+ ((-1)*(((30)*CeIV)*BrMA))); IF bj_ THEN BEGIN jj_[1, 1]:=((((((-1)*j0)+((-1)*((2000000)*Br_m)))+(-3.960000e-01) -)+(-(((7000)*CeIV))))+((-2)*((3000)*(HBrO2*(2))))); +)-((7000)*CeIV))+((-2)*((3000)*(HBrO2*(2))))); jj_[1, 2]:=((2.400000e-02)+((-1)*((2000000)*HBrO2))); jj_[1, 3]:=((((62000)*BrO2)*(-1))-((7000)*HBrO2)); jj_[1, 5]:=(((-1)*(-((((700000)*(BrO2*(2)))*(5.550000e+01))))) diff --git a/test/expected/burst.kcd.m2/model.c b/test/expected/burst.kcd.m2/model.c index 9ed3db8..212f37d 100644 --- a/test/expected/burst.kcd.m2/model.c +++ b/test/expected/burst.kcd.m2/model.c @@ -162,9 +162,9 @@ void calc_jac(double S[equa], double tk, double R[equa], double Jac[equa+1][equa H2O=5.550000e+01; CeIII=(8.600000e-05-CeIV); MA=1.670000e-01; -Jac[1][1]=tk*((((((-8.500000e-05-(-((3.300000e+00*HBrO))))+(-1.000000e+00 -*(2.000000e+06*Br_m)))+-3.960000e-01)+(-((7.000000e+03 -*CeIV))))+(-2.000000e+00*(3.000000e+03*(HBrO2*2.000000e+00 +Jac[1][1]=tk*((((((-8.500000e-05-(3.300000e+00*HBrO))+(-1.000000e+00 +*(2.000000e+06*Br_m)))+-3.960000e-01)-(7.000000e+03* +CeIV))+(-2.000000e+00*(3.000000e+03*(HBrO2*2.000000e+00 )))))-(1+4*R[0]); Jac[1][2]=tk*((2.400000e-02+(-1.000000e+00*(2.000000e+06 *HBrO2)))); @@ -198,7 +198,7 @@ Jac[4][1]=tk*((((-((3.300000e+00*HBrO)))+(2.000000e+00*(2.000000e+06 Jac[4][2]=tk*((2.400000e-02+(2.000000e+00*(2.000000e+06 *HBrO2)))); Jac[4][3]=tk*(0.000000e+00); -Jac[4][4]=tk*(((((-8.500000e-05+(-((3.300000e+00*HBrO2))))+(2.000000e+00 +Jac[4][4]=tk*(((((-8.500000e-05-(3.300000e+00*HBrO2))+(2.000000e+00 *(-((2.500000e-05*(HBrO*2.000000e+00))))))+-9.000000e-11 )+-2.738800e+00))-(1+4*R[3]); Jac[4][5]=tk*(0.000000e+00); @@ -316,9 +316,9 @@ BrMA=S[5]; H2O=5.550000e+01; CeIII=(8.600000e-05-CeIV); MA=1.670000e-01; -Jac[0][0]=(((((-8.500000e-05-(-((3.300000e+00*HBrO))))+(-1.000000e+00 -*(2.000000e+06*Br_m)))+-3.960000e-01)+(-((7.000000e+03 -*CeIV))))+(-2.000000e+00*(3.000000e+03*(HBrO2*2.000000e+00 +Jac[0][0]=(((((-8.500000e-05-(3.300000e+00*HBrO))+(-1.000000e+00 +*(2.000000e+06*Br_m)))+-3.960000e-01)-(7.000000e+03* +CeIV))+(-2.000000e+00*(3.000000e+03*(HBrO2*2.000000e+00 )))); Jac[0][1]=(2.400000e-02+(-1.000000e+00*(2.000000e+06 *HBrO2))); @@ -352,7 +352,7 @@ Jac[3][0]=(((-((3.300000e+00*HBrO)))+(2.000000e+00*(2.000000e+06 Jac[3][1]=(2.400000e-02+(2.000000e+00*(2.000000e+06 *HBrO2))); Jac[3][2]=0.000000e+00; -Jac[3][3]=((((-8.500000e-05+(-((3.300000e+00*HBrO2))))+(2.000000e+00 +Jac[3][3]=((((-8.500000e-05-(3.300000e+00*HBrO2))+(2.000000e+00 *(-((2.500000e-05*(HBrO*2.000000e+00))))))+-9.000000e-11 )+-2.738800e+00); Jac[3][4]=0.000000e+00; diff --git a/test/expected/burst.kcd.m3/model.c b/test/expected/burst.kcd.m3/model.c index 912f41a..61f423b 100644 --- a/test/expected/burst.kcd.m3/model.c +++ b/test/expected/burst.kcd.m3/model.c @@ -64,9 +64,9 @@ CeIV=S_[2]; HBrO=S_[3]; BrO2=S_[4]; BrMA=S_[5]; -jacobi_matx[0][0]=(((((-8.500000e-05-(-((3.300000e+00*HBrO))))+(-1.000000e+00 -*(2.000000e+06*Br_m)))+-3.960000e-01)+(-((7.000000e+03 -*CeIV))))+(-2.000000e+00*(3.000000e+03*(HBrO2*2.000000e+00 +jacobi_matx[0][0]=(((((-8.500000e-05-(3.300000e+00*HBrO))+(-1.000000e+00 +*(2.000000e+06*Br_m)))+-3.960000e-01)-(7.000000e+03* +CeIV))+(-2.000000e+00*(3.000000e+03*(HBrO2*2.000000e+00 )))); jacobi_matx[0][1]=(2.400000e-02+(-1.000000e+00*(2.000000e+06 *HBrO2))); @@ -95,7 +95,7 @@ jacobi_matx[3][0]=(((-((3.300000e+00*HBrO)))+(2.000000e+00*(2.000000e+06 *Br_m)))+(3.000000e+03*(HBrO2*2.000000e+00))); jacobi_matx[3][1]=(2.400000e-02+(2.000000e+00*(2.000000e+06 *HBrO2))); -jacobi_matx[3][3]=((((-8.500000e-05+(-((3.300000e+00*HBrO2))))+(2.000000e+00 +jacobi_matx[3][3]=((((-8.500000e-05-(3.300000e+00*HBrO2))+(2.000000e+00 *(-((2.500000e-05*(HBrO*2.000000e+00))))))+-9.000000e-11 )+-2.738800e+00); jacobi_matx[4][0]=(7.920000e-01+(-1.000000e+00*(-((7.000000e+03 diff --git a/test/expected/burst3.13.m2/model.c b/test/expected/burst3.13.m2/model.c index e3fa03a..a7594a1 100644 --- a/test/expected/burst3.13.m2/model.c +++ b/test/expected/burst3.13.m2/model.c @@ -153,7 +153,7 @@ void calc_jac(double S[equa], double tk, double R[equa], double Jac[equa+1][equa CeIII=(8.600000e-05-CeIV); MA=1.670000e-01; Jac[1][1]=tk*(((((-9.000000e-05+(-1.000000e+00*(2.000000e+06 -*Br_m)))+-3.960000e-01)+(-((7.000000e+03*CeIV))))+(-2.000000e+00 +*Br_m)))+-3.960000e-01)-(7.000000e+03*CeIV))+(-2.000000e+00 *(3.000000e+03*(HBrO2*2.000000e+00)))))-(1+4*R[0]); Jac[1][2]=tk*((2.400000e-02+(-1.000000e+00*(2.000000e+06 *HBrO2)))); @@ -296,7 +296,7 @@ BrMA=S[5]; CeIII=(8.600000e-05-CeIV); MA=1.670000e-01; Jac[0][0]=((((-9.000000e-05+(-1.000000e+00*(2.000000e+06 -*Br_m)))+-3.960000e-01)+(-((7.000000e+03*CeIV))))+(-2.000000e+00 +*Br_m)))+-3.960000e-01)-(7.000000e+03*CeIV))+(-2.000000e+00 *(3.000000e+03*(HBrO2*2.000000e+00)))); Jac[0][1]=(2.400000e-02+(-1.000000e+00*(2.000000e+06 *HBrO2))); diff --git a/test/expected/burst3.13.m3/model.c b/test/expected/burst3.13.m3/model.c index a98fffd..b1d6f6f 100644 --- a/test/expected/burst3.13.m3/model.c +++ b/test/expected/burst3.13.m3/model.c @@ -60,7 +60,7 @@ HBrO=S_[3]; BrO2=S_[4]; BrMA=S_[5]; jacobi_matx[0][0]=((((-9.000000e-05+(-1.000000e+00*(2.000000e+06 -*Br_m)))+-3.960000e-01)+(-((7.000000e+03*CeIV))))+(-2.000000e+00 +*Br_m)))+-3.960000e-01)-(7.000000e+03*CeIV))+(-2.000000e+00 *(3.000000e+03*(HBrO2*2.000000e+00)))); jacobi_matx[0][1]=(2.400000e-02+(-1.000000e+00*(2.000000e+06 *HBrO2))); diff --git a/test/expected/burst3.des.m2/model.c b/test/expected/burst3.des.m2/model.c index 668b116..bdd1cf3 100644 --- a/test/expected/burst3.des.m2/model.c +++ b/test/expected/burst3.des.m2/model.c @@ -153,7 +153,7 @@ void calc_jac(double S[equa], double tk, double R[equa], double Jac[equa+1][equa CeIII=(8.600000e-05-CeIV); MA=1.670000e-01; Jac[1][1]=tk*((((((-1.000000e+00*j0)+(-1.000000e+00*(2.000000e+06 -*Br_m)))+-3.960000e-01)+(-((7.000000e+03*CeIV))))+(-2.000000e+00 +*Br_m)))+-3.960000e-01)-(7.000000e+03*CeIV))+(-2.000000e+00 *(3.000000e+03*(HBrO2*2.000000e+00)))))-(1+4*R[0]); Jac[1][2]=tk*((2.400000e-02+(-1.000000e+00*(2.000000e+06 *HBrO2)))); @@ -296,7 +296,7 @@ BrMA=S[5]; CeIII=(8.600000e-05-CeIV); MA=1.670000e-01; Jac[0][0]=(((((-1.000000e+00*j0)+(-1.000000e+00*(2.000000e+06 -*Br_m)))+-3.960000e-01)+(-((7.000000e+03*CeIV))))+(-2.000000e+00 +*Br_m)))+-3.960000e-01)-(7.000000e+03*CeIV))+(-2.000000e+00 *(3.000000e+03*(HBrO2*2.000000e+00)))); Jac[0][1]=(2.400000e-02+(-1.000000e+00*(2.000000e+06 *HBrO2))); diff --git a/test/expected/burst3.des.m3/model.c b/test/expected/burst3.des.m3/model.c index 9ed18cb..82894fe 100644 --- a/test/expected/burst3.des.m3/model.c +++ b/test/expected/burst3.des.m3/model.c @@ -60,7 +60,7 @@ HBrO=S_[3]; BrO2=S_[4]; BrMA=S_[5]; jacobi_matx[0][0]=(((((-1.000000e+00*j0)+(-1.000000e+00*(2.000000e+06 -*Br_m)))+-3.960000e-01)+(-((7.000000e+03*CeIV))))+(-2.000000e+00 +*Br_m)))+-3.960000e-01)-(7.000000e+03*CeIV))+(-2.000000e+00 *(3.000000e+03*(HBrO2*2.000000e+00)))); jacobi_matx[0][1]=(2.400000e-02+(-1.000000e+00*(2.000000e+06 *HBrO2))); diff --git a/test/expected/burst3.des.m4/model.f b/test/expected/burst3.des.m4/model.f index 80c7b46..b93a2f3 100644 --- a/test/expected/burst3.des.m4/model.f +++ b/test/expected/burst3.des.m4/model.f @@ -64,7 +64,7 @@ subroutine model(ndim,nvar,n,tvar,xvar,fvar,gvar) &*BrMA))) gvar(1,1) = ((((((-1.000000e+00)*j0)+((-1.000000e+00)*((2.000000e+06) - &*Br_m)))+(-3.960000e-01))+(-(((7.000000e+03)*CeIV))))+((-2.000000e+00) + &*Br_m)))+(-3.960000e-01))-((7.000000e+03)*CeIV))+((-2.000000e+00) &*((3.000000e+03)*(HBrO2*(2.000000e+00))))) gvar(1,2) = ((2.400000e-02)+((-1.000000e+00)*((2.000000e+06) &*HBrO2))) diff --git a/test/expected/burst3.des.m5/kcm5proc.p b/test/expected/burst3.des.m5/kcm5proc.p index 63bcecf..1b86333 100644 --- a/test/expected/burst3.des.m5/kcm5proc.p +++ b/test/expected/burst3.des.m5/kcm5proc.p @@ -268,7 +268,7 @@ vv_[6]:=((((-1)*(j0*BrMA))+(((8.200000e+00)*HBrO)*(1.670000e-01) ))+((-1)*(((30)*CeIV)*BrMA))); IF bj_ THEN BEGIN jj_[1, 1]:=((((((-1)*j0)+((-1)*((2000000)*Br_m)))+(-3.960000e-01) -)+(-(((7000)*CeIV))))+((-2)*((3000)*(HBrO2*(2))))); +)-((7000)*CeIV))+((-2)*((3000)*(HBrO2*(2))))); jj_[1, 2]:=((2.400000e-02)+((-1)*((2000000)*HBrO2))); jj_[1, 3]:=((((62000)*BrO2)*(-1))-((7000)*HBrO2)); jj_[1, 5]:=(((-1)*(-((((700000)*(BrO2*(2)))*(5.550000e+01))))) diff --git a/test/expected/gtf.des.m1/stdout b/test/expected/gtf.des.m1/stdout index 4bcc578..d2bdb30 100644 --- a/test/expected/gtf.des.m1/stdout +++ b/test/expected/gtf.des.m1/stdout @@ -114,9 +114,9 @@ Constants declared: kf66 = 2.000000e+03 kf67 = 1.000000e+02 The Jacobian matrix is: -J(1, 1) = -7.35127763540812e-01 +J(1, 1) = -7.35127922008129e-01 J(1, 2) = -6.58368374088035e+00 -J(1, 3) = 8.46589230910298e-06 +J(1, 3) = -8.46548404992460e-06 J(1, 4) = 0.00000000000000e+00 J(1, 5) = -1.09025418521639e-04 J(1, 6) = 2.20000000000000e+03 @@ -162,9 +162,9 @@ J(2, 22) = 1.90991901052939e+04 J(2, 23) = 0.00000000000000e+00 J(3, 1) = 2.97496496207788e-01 J(3, 2) = -5.79660586629746e+01 -J(3, 3) = -4.98572947496975e+02 +J(3, 3) = -4.98572947497178e+02 J(3, 4) = 2.00000000000000e+00 -J(3, 5) = 1.81957342457342e-07 +J(3, 5) = 1.81957341992744e-07 J(3, 6) = 0.00000000000000e+00 J(3, 7) = 0.00000000000000e+00 J(3, 8) = 0.00000000000000e+00 @@ -208,9 +208,9 @@ J(4, 22) = -2.36596491731689e+01 J(4, 23) = 0.00000000000000e+00 J(5, 1) = -4.31579974832296e-01 J(5, 2) = -3.49450993819634e-02 -J(5, 3) = 8.46578976410440e-06 +J(5, 3) = 8.46558659492318e-06 J(5, 4) = 0.00000000000000e+00 -J(5, 5) = -4.48225515219777e-02 +J(5, 5) = -4.48225515219781e-02 J(5, 6) = 2.20000000000000e+03 J(5, 7) = 0.00000000000000e+00 J(5, 8) = 0.00000000000000e+00 @@ -330,11 +330,11 @@ J(10, 6) = 0.00000000000000e+00 J(10, 7) = 0.00000000000000e+00 J(10, 8) = -1.63782998919487e+04 J(10, 9) = -3.76805719221358e-02 -J(10, 10) = 5.51839872099070e-02 +J(10, 10) = -9.33502082222414e-02 J(10, 11) = 2.00000000000000e+02 J(10, 12) = 3.32980436820214e+04 J(10, 13) = 4.77952011301852e-05 -J(10, 14) = 8.23694514710454e+01 +J(10, 14) = -8.14135474484416e+01 J(10, 15) = 0.00000000000000e+00 J(10, 16) = 4.77952011301852e-05 J(10, 17) = -1.63782998919487e+04 @@ -426,7 +426,7 @@ J(14, 10) = -2.28689007834848e-09 J(14, 11) = 0.00000000000000e+00 J(14, 12) = 1.89173420836173e+02 J(14, 13) = 9.37238454669295e-01 -J(14, 14) = -9.71280958316313e+03 +J(14, 14) = -9.91118498285325e+03 J(14, 15) = 0.00000000000000e+00 J(14, 16) = -2.28689007834848e-08 J(14, 17) = 3.78351415452503e+02 @@ -472,7 +472,7 @@ J(16, 10) = 7.42670977160742e-02 J(16, 11) = 0.00000000000000e+00 J(16, 12) = 1.14325872599054e+03 J(16, 13) = 1.48534195432148e-01 -J(16, 14) = 7.59967177546059e+02 +J(16, 14) = 7.25374776775425e+02 J(16, 15) = 1.00000000000000e+00 J(16, 16) = -1.58095870988951e-01 J(16, 17) = 5.10028365263519e+04 @@ -498,7 +498,7 @@ J(17, 13) = -1.48534195432148e-01 J(17, 14) = -7.25374776775425e+02 J(17, 15) = 0.00000000000000e+00 J(17, 16) = 1.57789750936222e-01 -J(17, 17) = -2.04543631628787e+04 +J(17, 17) = -5.32175168015585e+04 J(17, 18) = 0.00000000000000e+00 J(17, 19) = 0.00000000000000e+00 J(17, 20) = 0.00000000000000e+00 @@ -670,532 +670,532 @@ The eigenvalues are: (-3.0600000173e-04, 0.0000000000e+00) The eigenvectors are: - (-1.1827533486e-02, 0.0000000000e+00) - (1.0000000000e+00, 0.0000000000e+00) - (1.8645655889e-02, 0.0000000000e+00) - (-2.4852738846e-03, 0.0000000000e+00) - (1.2089865851e-05, 0.0000000000e+00) - (-2.4577299222e-04, 0.0000000000e+00) - (1.3840311466e-02, 0.0000000000e+00) - (-7.0882798261e-03, 0.0000000000e+00) - (2.2628875682e-04, 0.0000000000e+00) - (1.2920357737e-01, 0.0000000000e+00) - (2.9562139592e-04, 0.0000000000e+00) - (-1.3053849409e-01, 0.0000000000e+00) - (-1.3826950799e-02, 0.0000000000e+00) - (1.2176657432e-02, 0.0000000000e+00) - (1.9554166470e-03, 0.0000000000e+00) - (-1.7708625894e-02, 0.0000000000e+00) - (8.6189333284e-03, 0.0000000000e+00) - (-3.2136123114e-03, 0.0000000000e+00) - (-8.6177906580e-04, 0.0000000000e+00) - (-5.7546164043e-04, 0.0000000000e+00) - (8.3260886525e-03, 0.0000000000e+00) - (-7.0832563181e-02, 0.0000000000e+00) + (3.1198654180e-02, 0.0000000000e+00) + (-1.0000000000e+00, 0.0000000000e+00) + (2.0345838320e-02, 0.0000000000e+00) + (3.9600847576e-03, 0.0000000000e+00) + (-2.6146488383e-05, 0.0000000000e+00) + (5.5030628581e-04, 0.0000000000e+00) + (-2.7716561864e-02, 0.0000000000e+00) + (5.8640701563e-03, 0.0000000000e+00) + (-4.4215344809e-04, 0.0000000000e+00) + (-8.9818042923e-02, 0.0000000000e+00) + (4.1373697118e-04, 0.0000000000e+00) + (1.1544417152e-01, 0.0000000000e+00) + (-4.5822471063e-04, 0.0000000000e+00) + (-2.3173510384e-02, 0.0000000000e+00) + (-2.0590433306e-03, 0.0000000000e+00) + (-6.5252976042e-02, 0.0000000000e+00) + (6.5618615438e-02, 0.0000000000e+00) + (4.0251772250e-04, 0.0000000000e+00) + (4.9331698289e-04, 0.0000000000e+00) + (-1.8459279980e-03, 0.0000000000e+00) + (4.2097038129e-02, 0.0000000000e+00) + (5.9514872348e-02, 0.0000000000e+00) (0.0000000000e+00, 0.0000000000e+00) - (1.0214819272e+00, 0.0000000000e+00) + (-9.6741602147e-01, 0.0000000000e+00) (1.0000000000e+00, 0.0000000000e+00) - (-3.0565126933e-01, 0.0000000000e+00) - (-8.6528828813e-02, 0.0000000000e+00) - (-1.8640957593e-04, 0.0000000000e+00) - (8.1174924522e-03, 0.0000000000e+00) - (-1.1229946293e+00, 0.0000000000e+00) - (6.8213970774e-02, 0.0000000000e+00) - (1.1731182223e-02, 0.0000000000e+00) - (-1.3935745835e-02, 0.0000000000e+00) - (-6.9425945486e-03, 0.0000000000e+00) - (-5.1648278416e-02, 0.0000000000e+00) - (-5.4259449302e-01, 0.0000000000e+00) - (7.0752708172e-01, 0.0000000000e+00) - (-4.5778208052e-03, 0.0000000000e+00) - (-1.4168018411e+00, 0.0000000000e+00) - (5.4584109135e-01, 0.0000000000e+00) - (-7.4539879372e-02, 0.0000000000e+00) - (3.6133014622e-02, 0.0000000000e+00) - (-4.0863860624e-02, 0.0000000000e+00) - (-1.8073398699e-01, 0.0000000000e+00) - (3.4061272660e-01, 0.0000000000e+00) + (1.9490235467e-01, 0.0000000000e+00) + (8.0180574439e-02, 0.0000000000e+00) + (-1.2766438915e-04, 0.0000000000e+00) + (-1.6263609471e-02, 0.0000000000e+00) + (1.0740368165e+00, 0.0000000000e+00) + (-1.6209064415e-01, 0.0000000000e+00) + (-1.7037093126e-02, 0.0000000000e+00) + (-6.9788634823e-01, 0.0000000000e+00) + (4.0079054989e-03, 0.0000000000e+00) + (1.0859285348e+00, 0.0000000000e+00) + (3.4484228921e-01, 0.0000000000e+00) + (-8.4184021322e-01, 0.0000000000e+00) + (-1.1634434911e-02, 0.0000000000e+00) + (2.3205315903e-01, 0.0000000000e+00) + (-1.9606039141e-01, 0.0000000000e+00) + (1.0930793045e-01, 0.0000000000e+00) + (-4.5456578293e-02, 0.0000000000e+00) + (3.8793098075e-03, 0.0000000000e+00) + (7.4465325094e-01, 0.0000000000e+00) + (-5.8440908468e-01, 0.0000000000e+00) (0.0000000000e+00, 0.0000000000e+00) - (-8.8517450967e-03, 0.0000000000e+00) - (1.0000000000e+00, 0.0000000000e+00) - (-1.3783666848e-01, 0.0000000000e+00) - (-1.9284414160e-02, 0.0000000000e+00) - (-1.7017545029e-04, 0.0000000000e+00) - (4.8369511080e-03, 0.0000000000e+00) - (-1.8181740035e-02, 0.0000000000e+00) - (-8.0253777393e-03, 0.0000000000e+00) - (-7.4281976897e-04, 0.0000000000e+00) - (-2.2703130797e-01, 0.0000000000e+00) - (-2.6545161442e-03, 0.0000000000e+00) - (1.8706491439e-01, 0.0000000000e+00) - (6.3950978508e-02, 0.0000000000e+00) - (-2.4516501815e-02, 0.0000000000e+00) - (-2.2369899673e-03, 0.0000000000e+00) - (5.4276774150e-02, 0.0000000000e+00) - (-2.3097297752e-02, 0.0000000000e+00) - (1.9378549224e-02, 0.0000000000e+00) - (1.1235762308e-03, 0.0000000000e+00) - (1.7240217585e-03, 0.0000000000e+00) - (-9.3423023821e-02, 0.0000000000e+00) - (6.1565455288e-03, 0.0000000000e+00) + (-4.3624726620e-02, 0.0000000000e+00) + (-1.0000000000e+00, 0.0000000000e+00) + (-6.9282830289e-02, 0.0000000000e+00) + (2.1263510297e-02, 0.0000000000e+00) + (-3.8498257989e-05, 0.0000000000e+00) + (2.8646974845e-04, 0.0000000000e+00) + (3.1200021140e-02, 0.0000000000e+00) + (9.6364617705e-03, 0.0000000000e+00) + (1.0103560597e-03, 0.0000000000e+00) + (8.9909364555e-03, 0.0000000000e+00) + (-9.7633887933e-04, 0.0000000000e+00) + (-2.8062258811e-02, 0.0000000000e+00) + (-3.7086354419e-02, 0.0000000000e+00) + (6.2596991747e-02, 0.0000000000e+00) + (1.1090388231e-03, 0.0000000000e+00) + (1.0794100989e-01, 0.0000000000e+00) + (-1.1320232179e-01, 0.0000000000e+00) + (-3.4142854465e-03, 0.0000000000e+00) + (-8.4404179178e-05, 0.0000000000e+00) + (2.9726501449e-03, 0.0000000000e+00) + (-3.7659212077e-02, 0.0000000000e+00) + (-6.3033932474e-02, 0.0000000000e+00) (0.0000000000e+00, 0.0000000000e+00) - (-3.0693117674e-01, 0.0000000000e+00) + (-4.5781562370e-01, 0.0000000000e+00) (1.0000000000e+00, 0.0000000000e+00) - (1.3879481743e-01, 0.0000000000e+00) - (-4.1404638994e-02, 0.0000000000e+00) - (4.2100652797e-04, 0.0000000000e+00) - (-1.0950174752e-02, 0.0000000000e+00) - (3.5620370783e-01, 0.0000000000e+00) - (8.6387362039e-03, 0.0000000000e+00) - (-2.1081119115e-03, 0.0000000000e+00) - (2.5510406504e-01, 0.0000000000e+00) - (1.8633930535e-03, 0.0000000000e+00) - (-3.0690588372e-01, 0.0000000000e+00) - (1.8930178020e-01, 0.0000000000e+00) - (-1.6789686626e-01, 0.0000000000e+00) - (4.3611772427e-03, 0.0000000000e+00) - (2.1334018012e-01, 0.0000000000e+00) - (-7.4335644222e-02, 0.0000000000e+00) - (1.5068512806e-02, 0.0000000000e+00) - (-1.3080773111e-02, 0.0000000000e+00) - (5.8221217936e-03, 0.0000000000e+00) - (-8.1872605393e-02, 0.0000000000e+00) - (2.3013634195e-01, 0.0000000000e+00) + (7.7147209913e-02, 0.0000000000e+00) + (-3.8301001147e-02, 0.0000000000e+00) + (-6.5100807516e-04, 0.0000000000e+00) + (2.6094796599e-02, 0.0000000000e+00) + (3.7879002518e-01, 0.0000000000e+00) + (7.8338866213e-03, 0.0000000000e+00) + (-1.2337256654e-04, 0.0000000000e+00) + (-2.0823091819e-01, 0.0000000000e+00) + (-7.9602871079e-04, 0.0000000000e+00) + (3.6329236021e-02, 0.0000000000e+00) + (2.4605993045e-01, 0.0000000000e+00) + (-1.0238100512e-01, 0.0000000000e+00) + (4.3578694219e-03, 0.0000000000e+00) + (1.4618429764e+00, 0.0000000000e+00) + (-1.5016216436e+00, 0.0000000000e+00) + (2.8346788259e-02, 0.0000000000e+00) + (-3.6613839320e-03, 0.0000000000e+00) + (3.7929123666e-02, 0.0000000000e+00) + (-3.9167279908e-01, 0.0000000000e+00) + (9.7859454388e-02, 0.0000000000e+00) (0.0000000000e+00, 0.0000000000e+00) - (-1.9363886815e-01, 0.0000000000e+00) + (-5.1989456566e-01, 0.0000000000e+00) (-1.0000000000e+00, 0.0000000000e+00) - (-5.7428175473e-01, 0.0000000000e+00) - (2.6635074312e-03, 0.0000000000e+00) - (1.5589991338e-03, 0.0000000000e+00) - (-6.3396789976e-02, 0.0000000000e+00) - (2.2322301146e-01, 0.0000000000e+00) - (6.1249197555e-03, 0.0000000000e+00) - (1.4949449708e-03, 0.0000000000e+00) - (-1.3909908491e-01, 0.0000000000e+00) - (-1.0981673981e-02, 0.0000000000e+00) - (-3.3001841121e-04, 0.0000000000e+00) - (-4.9755276762e-03, 0.0000000000e+00) - (1.5638495531e-01, 0.0000000000e+00) - (-2.3860400716e-04, 0.0000000000e+00) - (-5.2484720861e-01, 0.0000000000e+00) - (2.1980093257e-01, 0.0000000000e+00) - (3.9508775495e-02, 0.0000000000e+00) - (-8.8646877446e-03, 0.0000000000e+00) - (-1.8296711484e-02, 0.0000000000e+00) - (-3.3586346635e-01, 0.0000000000e+00) - (2.0963615541e-01, 0.0000000000e+00) + (6.8910704956e-01, 0.0000000000e+00) + (1.5102711359e-02, 0.0000000000e+00) + (8.5285246018e-04, 0.0000000000e+00) + (-2.4729451924e-02, 0.0000000000e+00) + (6.8063230053e-01, 0.0000000000e+00) + (8.0712803861e-04, 0.0000000000e+00) + (-3.7578895301e-03, 0.0000000000e+00) + (7.9719326071e-01, 0.0000000000e+00) + (1.2313458998e-02, 0.0000000000e+00) + (-6.4812781531e-01, 0.0000000000e+00) + (1.0046345688e-01, 0.0000000000e+00) + (-3.0575587473e-01, 0.0000000000e+00) + (9.6954365700e-03, 0.0000000000e+00) + (4.1766377211e-01, 0.0000000000e+00) + (-3.4835996204e-01, 0.0000000000e+00) + (-2.3274560363e-02, 0.0000000000e+00) + (-2.5170945733e-02, 0.0000000000e+00) + (1.1300905075e-02, 0.0000000000e+00) + (3.6777841388e-01, 0.0000000000e+00) + (-5.7568368079e-03, 0.0000000000e+00) (0.0000000000e+00, 0.0000000000e+00) - (-1.5557926238e+00, 0.0000000000e+00) + (-9.9792993287e-01, 0.0000000000e+00) + (-1.1871901893e+00, 0.0000000000e+00) (-1.0000000000e+00, 0.0000000000e+00) - (-2.0361420213e+00, 0.0000000000e+00) - (2.9710586345e-02, 0.0000000000e+00) - (-5.7395614993e-03, 0.0000000000e+00) - (1.5341561589e-01, 0.0000000000e+00) - (1.1311580101e+00, 0.0000000000e+00) - (1.4154712881e-01, 0.0000000000e+00) - (1.0409442605e-03, 0.0000000000e+00) - (2.1467805461e-01, 0.0000000000e+00) - (-3.2805364026e-02, 0.0000000000e+00) - (-2.6737142533e-01, 0.0000000000e+00) - (-4.3579747597e-01, 0.0000000000e+00) - (5.3574206170e-01, 0.0000000000e+00) - (-9.0805124856e-04, 0.0000000000e+00) - (-3.5187804982e+00, 0.0000000000e+00) - (1.4704645394e+00, 0.0000000000e+00) - (8.0168724793e-02, 0.0000000000e+00) - (-9.6479098112e-02, 0.0000000000e+00) - (-9.5855409120e-02, 0.0000000000e+00) - (-7.6505831180e-03, 0.0000000000e+00) - (5.1377055312e-01, 0.0000000000e+00) + (-2.0459075733e-02, 0.0000000000e+00) + (-4.7250876918e-03, 0.0000000000e+00) + (1.5233380991e-01, 0.0000000000e+00) + (6.7550981053e-01, 0.0000000000e+00) + (3.2437880344e-02, 0.0000000000e+00) + (5.2595813667e-03, 0.0000000000e+00) + (-2.2232889563e-01, 0.0000000000e+00) + (-1.5155901311e-02, 0.0000000000e+00) + (3.2906183310e-02, 0.0000000000e+00) + (-2.4261685796e-01, 0.0000000000e+00) + (4.8795602636e-01, 0.0000000000e+00) + (9.8944869712e-04, 0.0000000000e+00) + (-4.3691691101e-01, 0.0000000000e+00) + (4.4431612490e-01, 0.0000000000e+00) + (3.1847417626e-03, 0.0000000000e+00) + (-4.4762308342e-02, 0.0000000000e+00) + (-3.3809298869e-03, 0.0000000000e+00) + (-2.6848535158e-01, 0.0000000000e+00) + (5.1552350569e-01, 0.0000000000e+00) (0.0000000000e+00, 0.0000000000e+00) - (4.5701016062e-03, 0.0000000000e+00) - (1.0000000000e+00, 0.0000000000e+00) - (-9.8288686415e-02, 0.0000000000e+00) - (9.5393789351e-03, 0.0000000000e+00) - (-1.9690685862e-04, 0.0000000000e+00) - (3.4013744486e-03, 0.0000000000e+00) - (-2.9558979136e-02, 0.0000000000e+00) - (-2.1262243649e-02, 0.0000000000e+00) - (-1.5992961801e-03, 0.0000000000e+00) - (3.8000603486e-02, 0.0000000000e+00) - (-2.0850691451e-03, 0.0000000000e+00) - (-3.2446886731e-02, 0.0000000000e+00) - (5.6355507776e-02, 0.0000000000e+00) - (-6.8623850798e-02, 0.0000000000e+00) - (-1.5731136480e-03, 0.0000000000e+00) - (-5.9315485799e-01, 0.0000000000e+00) - (2.3281895935e-01, 0.0000000000e+00) - (2.1477653756e-02, 0.0000000000e+00) - (-5.2593930753e-03, 0.0000000000e+00) - (-1.8846863363e-02, 0.0000000000e+00) - (-2.0203829471e-02, 0.0000000000e+00) - (2.1566395245e-01, 0.0000000000e+00) + (2.3907768182e+00, 0.0000000000e+00) + (-2.9994319441e-01, 0.0000000000e+00) + (3.7337455910e+00, 0.0000000000e+00) + (1.2235734615e-01, 0.0000000000e+00) + (-6.4429910606e-03, 0.0000000000e+00) + (2.5794197599e-01, 0.0000000000e+00) + (-2.5061651386e+00, 0.0000000000e+00) + (-1.8214280226e-01, 0.0000000000e+00) + (-1.0377637775e-02, 0.0000000000e+00) + (1.8944570393e+00, 0.0000000000e+00) + (6.4490845113e-02, 0.0000000000e+00) + (-7.4764891985e-01, 0.0000000000e+00) + (-2.2590984478e-01, 0.0000000000e+00) + (-1.0000000000e+00, 0.0000000000e+00) + (1.7274415438e-03, 0.0000000000e+00) + (-1.3974749129e-01, 0.0000000000e+00) + (2.9595641591e-01, 0.0000000000e+00) + (-2.1335254674e-01, 0.0000000000e+00) + (7.9386351686e-02, 0.0000000000e+00) + (-1.0392358225e-02, 0.0000000000e+00) + (2.3011114965e+00, 0.0000000000e+00) + (-1.3459854922e+00, 0.0000000000e+00) (0.0000000000e+00, 0.0000000000e+00) - (-6.0576208504e-02, 0.0000000000e+00) - (-1.0000000000e+00, 0.0000000000e+00) - (2.1633217098e-01, 0.0000000000e+00) - (-7.9354827612e-03, 0.0000000000e+00) - (-7.9790670288e-05, 0.0000000000e+00) - (-3.4445274200e-03, 0.0000000000e+00) - (1.0169194967e-01, 0.0000000000e+00) - (-3.3848922869e-03, 0.0000000000e+00) - (-5.7985695449e-04, 0.0000000000e+00) - (1.5740586650e-01, 0.0000000000e+00) - (3.3803822694e-03, 0.0000000000e+00) - (5.8015264440e-02, 0.0000000000e+00) - (-2.2256720530e-01, 0.0000000000e+00) - (1.7168268863e-02, 0.0000000000e+00) - (-1.7447533118e-03, 0.0000000000e+00) - (-5.2354336041e-01, 0.0000000000e+00) - (2.0742229043e-01, 0.0000000000e+00) - (-2.3628193074e-02, 0.0000000000e+00) - (-9.8286706964e-03, 0.0000000000e+00) - (-1.6249863505e-02, 0.0000000000e+00) - (4.2193242871e-01, 0.0000000000e+00) - (-1.5141870354e-01, 0.0000000000e+00) + (-2.1563903834e-01, 0.0000000000e+00) + (1.0000000000e+00, 0.0000000000e+00) + (-1.9343408961e-01, 0.0000000000e+00) + (1.4924783388e-02, 0.0000000000e+00) + (5.5871280245e-04, 0.0000000000e+00) + (-1.7304966713e-02, 0.0000000000e+00) + (3.2688871927e-01, 0.0000000000e+00) + (-4.6918444902e-02, 0.0000000000e+00) + (1.8983285150e-02, 0.0000000000e+00) + (-2.9101239104e-01, 0.0000000000e+00) + (9.2115994564e-04, 0.0000000000e+00) + (4.0373578989e-01, 0.0000000000e+00) + (-1.1496360527e+00, 0.0000000000e+00) + (1.2436476710e+00, 0.0000000000e+00) + (-3.3565366373e-03, 0.0000000000e+00) + (1.0120371679e-01, 0.0000000000e+00) + (-1.0381986135e-01, 0.0000000000e+00) + (-1.9147163027e-01, 0.0000000000e+00) + (-7.7814203764e-03, 0.0000000000e+00) + (1.7004194241e-02, 0.0000000000e+00) + (3.3775256127e-01, 0.0000000000e+00) + (4.1010135028e-01, 0.0000000000e+00) (0.0000000000e+00, 0.0000000000e+00) - (1.6180570198e-01, 0.0000000000e+00) + (2.3923820012e-02, 0.0000000000e+00) (1.0000000000e+00, 0.0000000000e+00) - (2.4043899898e-01, 0.0000000000e+00) - (3.1202557044e-03, 0.0000000000e+00) - (2.4437062001e-04, 0.0000000000e+00) - (-7.1180512004e-03, 0.0000000000e+00) - (-1.7347676057e-01, 0.0000000000e+00) - (2.6587257713e-02, 0.0000000000e+00) - (-9.0023142508e-03, 0.0000000000e+00) - (1.2749275624e-01, 0.0000000000e+00) - (2.2927838496e-03, 0.0000000000e+00) - (-1.4459424585e-01, 0.0000000000e+00) - (5.4530577344e-01, 0.0000000000e+00) - (-6.0655073639e-01, 0.0000000000e+00) - (1.5281712340e-03, 0.0000000000e+00) - (2.3026188652e-01, 0.0000000000e+00) - (-1.2304777303e-01, 0.0000000000e+00) - (8.1915998468e-02, 0.0000000000e+00) - (8.4996237009e-03, 0.0000000000e+00) - (-6.1017778208e-04, 0.0000000000e+00) - (-1.1698324871e-01, 0.0000000000e+00) - (-2.5940185668e-01, 0.0000000000e+00) + (-3.3806069759e-01, 0.0000000000e+00) + (1.4943366107e-02, 0.0000000000e+00) + (5.7778914821e-05, 0.0000000000e+00) + (1.0820290361e-03, 0.0000000000e+00) + (-7.1333022217e-02, 0.0000000000e+00) + (-8.2945055661e-03, 0.0000000000e+00) + (-7.5836153606e-04, 0.0000000000e+00) + (-8.7320855684e-02, 0.0000000000e+00) + (-5.4337302672e-03, 0.0000000000e+00) + (-1.2668127083e-01, 0.0000000000e+00) + (2.5889496520e-01, 0.0000000000e+00) + (-6.6225843332e-02, 0.0000000000e+00) + (9.6543274050e-04, 0.0000000000e+00) + (-3.2936602200e-02, 0.0000000000e+00) + (1.2940683265e-02, 0.0000000000e+00) + (4.0915575404e-02, 0.0000000000e+00) + (2.8484650882e-03, 0.0000000000e+00) + (-3.5133328248e-04, 0.0000000000e+00) + (-4.2352291653e-01, 0.0000000000e+00) + (3.0771146263e-01, 0.0000000000e+00) (0.0000000000e+00, 0.0000000000e+00) - (2.3956638393e-01, 0.0000000000e+00) - (-9.6828620607e+00, 0.0000000000e+00) - (-3.7324143514e-01, 0.0000000000e+00) - (-3.1274344824e-02, 0.0000000000e+00) - (-2.9637612830e-04, 0.0000000000e+00) - (2.9506019433e-02, 0.0000000000e+00) - (-3.4685921266e-01, 0.0000000000e+00) - (-4.0683921656e-02, 0.0000000000e+00) - (-5.4139549941e-03, 0.0000000000e+00) - (-7.7676664766e-03, 0.0000000000e+00) - (-5.9263074925e-03, 0.0000000000e+00) - (-5.2495873566e-01, 0.0000000000e+00) - (9.0297646350e-01, 0.0000000000e+00) - (-4.5497133808e-01, 0.0000000000e+00) - (7.6701104767e-03, 0.0000000000e+00) - (9.4454321289e-01, 0.0000000000e+00) - (-3.8900966207e-01, 0.0000000000e+00) - (1.0424076717e-01, 0.0000000000e+00) - (2.1402515634e-02, 0.0000000000e+00) - (3.0850942401e-02, 0.0000000000e+00) - (-1.0000000000e+00, 0.0000000000e+00) - (2.1025150243e-01, 0.0000000000e+00) + (2.7015157144e-01, 0.0000000000e+00) + (9.3165850177e+00, 0.0000000000e+00) + (3.3384164618e-01, 0.0000000000e+00) + (3.5133544142e-02, 0.0000000000e+00) + (5.8325958813e-04, 0.0000000000e+00) + (4.3255716615e-03, 0.0000000000e+00) + (6.0627669842e-02, 0.0000000000e+00) + (4.9924107605e-02, 0.0000000000e+00) + (-1.5773553693e-03, 0.0000000000e+00) + (-2.2852066107e-02, 0.0000000000e+00) + (1.8114133580e-02, 0.0000000000e+00) + (2.9118819998e-01, 0.0000000000e+00) + (-2.2358793668e-01, 0.0000000000e+00) + (-1.1904285572e-02, 0.0000000000e+00) + (-7.3214104507e-03, 0.0000000000e+00) + (-2.8719545972e-02, 0.0000000000e+00) + (8.4881322495e-02, 0.0000000000e+00) + (-1.2673039659e-01, 0.0000000000e+00) + (-3.9126864545e-03, 0.0000000000e+00) + (3.4120927642e-02, 0.0000000000e+00) + (1.0000000000e+00, 0.0000000000e+00) + (-2.3642757745e-01, 0.0000000000e+00) (0.0000000000e+00, 0.0000000000e+00) - (5.6727568428e-01, 0.0000000000e+00) - (1.5527943243e-04, 0.0000000000e+00) - (3.2305968768e-05, 0.0000000000e+00) - (5.3243752367e-07, 0.0000000000e+00) - (1.5423352103e-03, 0.0000000000e+00) - (1.7792220369e-04, 0.0000000000e+00) - (-2.2824712716e-05, 0.0000000000e+00) - (1.1763678678e-06, 0.0000000000e+00) - (-1.8229678668e-03, 0.0000000000e+00) - (9.0530897472e-03, 0.0000000000e+00) - (2.1228143300e-02, 0.0000000000e+00) - (4.5000467054e-06, 0.0000000000e+00) - (1.5524152226e-02, 0.0000000000e+00) - (-1.2895347623e-05, 0.0000000000e+00) - (-6.8008376163e-03, 0.0000000000e+00) - (2.6973140473e-02, 0.0000000000e+00) - (-6.2421655571e-05, 0.0000000000e+00) - (-1.7940358465e-01, 0.0000000000e+00) - (-2.7594684802e-04, 0.0000000000e+00) - (7.0578212038e-02, 0.0000000000e+00) + (5.7907681036e-01, 0.0000000000e+00) + (-1.5616360254e-03, 0.0000000000e+00) + (-1.2226126704e-05, 0.0000000000e+00) + (-6.4944926017e-06, 0.0000000000e+00) + (1.7827790571e-03, 0.0000000000e+00) + (1.1448202757e-03, 0.0000000000e+00) + (-4.1258169092e-05, 0.0000000000e+00) + (-6.2265597433e-06, 0.0000000000e+00) + (-2.0894099650e-03, 0.0000000000e+00) + (1.5309975335e-02, 0.0000000000e+00) + (2.6258993409e-02, 0.0000000000e+00) + (-5.3459548008e-05, 0.0000000000e+00) + (1.2019617014e-02, 0.0000000000e+00) + (-2.8110776385e-05, 0.0000000000e+00) + (-6.6698827911e-03, 0.0000000000e+00) + (6.6270700935e-02, 0.0000000000e+00) + (1.5780196479e-04, 0.0000000000e+00) + (-1.8324605545e-01, 0.0000000000e+00) + (-9.4704066944e-06, 0.0000000000e+00) + (7.3650970340e-02, 0.0000000000e+00) (1.0000000000e+00, 0.0000000000e+00) - (-2.2391726832e-05, 0.0000000000e+00) + (-1.0019905266e-06, 0.0000000000e+00) (0.0000000000e+00, 0.0000000000e+00) - (5.7334950019e-01, 0.0000000000e+00) - (1.0691479685e-06, 0.0000000000e+00) - (-9.0091389498e-09, 0.0000000000e+00) - (1.9493654170e-09, 0.0000000000e+00) - (3.6398430695e-04, 0.0000000000e+00) - (-1.3161554526e-06, 0.0000000000e+00) - (2.1808977870e-07, 0.0000000000e+00) - (8.7248842615e-09, 0.0000000000e+00) - (-6.2418577450e-04, 0.0000000000e+00) - (3.8612909638e-02, 0.0000000000e+00) - (-1.5006790790e-04, 0.0000000000e+00) - (4.1162721334e-08, 0.0000000000e+00) - (7.4136304624e-03, 0.0000000000e+00) - (-4.0156775526e-08, 0.0000000000e+00) - (-6.6578971049e-03, 0.0000000000e+00) - (2.7243202549e-02, 0.0000000000e+00) - (5.9854599105e-07, 0.0000000000e+00) - (-1.8011335429e-01, 0.0000000000e+00) - (-1.3963357976e-04, 0.0000000000e+00) - (7.0309992986e-02, 0.0000000000e+00) + (5.8634378972e-01, 0.0000000000e+00) + (-8.6127439010e-06, 0.0000000000e+00) + (-2.3186423412e-07, 0.0000000000e+00) + (-3.0422654009e-08, 0.0000000000e+00) + (6.1826724450e-04, 0.0000000000e+00) + (5.9986756771e-06, 0.0000000000e+00) + (-2.0477147795e-07, 0.0000000000e+00) + (-4.4771384504e-08, 0.0000000000e+00) + (-7.0278025477e-04, 0.0000000000e+00) + (4.7518724558e-02, 0.0000000000e+00) + (1.4215998261e-04, 0.0000000000e+00) + (-3.2151053377e-07, 0.0000000000e+00) + (6.0040380659e-03, 0.0000000000e+00) + (-7.7770888933e-08, 0.0000000000e+00) + (-6.5544983698e-03, 0.0000000000e+00) + (6.6807389414e-02, 0.0000000000e+00) + (7.3695053924e-07, 0.0000000000e+00) + (-1.8375145595e-01, 0.0000000000e+00) + (2.1092751656e-04, 0.0000000000e+00) + (7.3309465764e-02, 0.0000000000e+00) (1.0000000000e+00, 0.0000000000e+00) - (-1.5994324270e-08, 0.0000000000e+00) + (1.6403501302e-07, 0.0000000000e+00) (0.0000000000e+00, 0.0000000000e+00) - (3.0480246386e-02, 0.0000000000e+00) - (1.4242983099e-07, 0.0000000000e+00) - (-1.4756185188e-08, 0.0000000000e+00) - (3.5520703455e-10, 0.0000000000e+00) - (1.8660297702e-01, 0.0000000000e+00) - (-2.2543520911e-07, 0.0000000000e+00) - (3.4479716722e-08, 0.0000000000e+00) - (8.5251029772e-10, 0.0000000000e+00) - (-3.1776093719e-02, 0.0000000000e+00) - (-5.1997595800e-01, 0.0000000000e+00) - (-2.6414946576e-05, 0.0000000000e+00) - (5.4307201071e-09, 0.0000000000e+00) - (5.5125775045e-01, 0.0000000000e+00) - (3.2290937932e-09, 0.0000000000e+00) - (-2.1266927151e-02, 0.0000000000e+00) - (1.2567976511e-02, 0.0000000000e+00) - (9.2352446685e-08, 0.0000000000e+00) - (-1.8404087287e-01, 0.0000000000e+00) - (-1.9340437890e-02, 0.0000000000e+00) - (1.5727861946e-01, 0.0000000000e+00) + (-1.9766454701e-02, 0.0000000000e+00) + (3.4661010192e-07, 0.0000000000e+00) + (8.1113650786e-09, 0.0000000000e+00) + (1.2031707823e-09, 0.0000000000e+00) + (2.3878826777e-01, 0.0000000000e+00) + (-3.5458415269e-07, 0.0000000000e+00) + (1.2041279679e-08, 0.0000000000e+00) + (1.6800917503e-09, 0.0000000000e+00) + (-4.7593298756e-02, 0.0000000000e+00) + (-4.9008017047e-01, 0.0000000000e+00) + (-8.2778158064e-06, 0.0000000000e+00) + (1.4598687174e-08, 0.0000000000e+00) + (5.2639444040e-01, 0.0000000000e+00) + (6.4956918921e-09, 0.0000000000e+00) + (-2.3094654846e-02, 0.0000000000e+00) + (3.5180530666e-02, 0.0000000000e+00) + (-4.7586271034e-08, 0.0000000000e+00) + (-2.1682642060e-01, 0.0000000000e+00) + (-2.4238499734e-02, 0.0000000000e+00) + (1.9388419560e-01, 0.0000000000e+00) (1.0000000000e+00, 0.0000000000e+00) - (8.1384952404e-09, 0.0000000000e+00) + (-5.2031596731e-09, 0.0000000000e+00) (0.0000000000e+00, 0.0000000000e+00) - (-1.1698597392e-03, 0.0000000000e+00) - (-1.7530559645e-09, 0.0000000000e+00) - (2.2617466921e-10, 0.0000000000e+00) - (-2.4899135584e-12, 0.0000000000e+00) - (4.1671687437e-01, 0.0000000000e+00) - (4.2255878237e-09, 0.0000000000e+00) - (-6.3662229712e-10, 0.0000000000e+00) - (-1.4655144334e-11, 0.0000000000e+00) - (3.7349310770e-02, 0.0000000000e+00) - (2.2250968165e-02, 0.0000000000e+00) - (4.8930920620e-07, 0.0000000000e+00) - (-5.6203062926e-11, 0.0000000000e+00) - (-6.9267802411e-03, 0.0000000000e+00) - (5.2344683200e-11, 0.0000000000e+00) - (-2.5970244906e-02, 0.0000000000e+00) - (9.2743584573e-02, 0.0000000000e+00) - (-1.7806629937e-09, 0.0000000000e+00) - (-3.8972565811e-01, 0.0000000000e+00) - (-4.2271064454e-02, 0.0000000000e+00) - (3.4259423997e-01, 0.0000000000e+00) + (-4.7341671537e-04, 0.0000000000e+00) + (6.4812902775e-09, 0.0000000000e+00) + (1.6575798718e-10, 0.0000000000e+00) + (2.2095981831e-11, 0.0000000000e+00) + (4.0976466607e-01, 0.0000000000e+00) + (-6.3562332032e-09, 0.0000000000e+00) + (2.1339902539e-10, 0.0000000000e+00) + (3.2603441493e-11, 0.0000000000e+00) + (3.7775200791e-02, 0.0000000000e+00) + (2.4112715654e-02, 0.0000000000e+00) + (-1.4935696809e-07, 0.0000000000e+00) + (2.7123351771e-10, 0.0000000000e+00) + (7.0964390505e-03, 0.0000000000e+00) + (1.0853223844e-10, 0.0000000000e+00) + (-2.5048346710e-02, 0.0000000000e+00) + (8.4428700601e-02, 0.0000000000e+00) + (-8.3156154966e-10, 0.0000000000e+00) + (-3.8214365111e-01, 0.0000000000e+00) + (-4.1166585355e-02, 0.0000000000e+00) + (3.3493079503e-01, 0.0000000000e+00) (1.0000000000e+00, 0.0000000000e+00) - (-1.0342047587e-10, 0.0000000000e+00) + (-1.1325923535e-10, 0.0000000000e+00) (0.0000000000e+00, 0.0000000000e+00) - (1.6603991736e-06, 0.0000000000e+00) - (4.9908815907e-12, 0.0000000000e+00) - (-4.5161939887e-13, 0.0000000000e+00) - (1.1250468222e-14, 0.0000000000e+00) - (4.2078165885e-01, 0.0000000000e+00) - (-8.1777055336e-12, 0.0000000000e+00) - (1.2536709910e-12, 0.0000000000e+00) - (3.3535453311e-14, 0.0000000000e+00) - (-3.6404515249e-05, 0.0000000000e+00) - (1.5843765017e-02, 0.0000000000e+00) - (-9.5249418962e-10, 0.0000000000e+00) - (1.7938020342e-13, 0.0000000000e+00) - (1.8987828452e-05, 0.0000000000e+00) - (5.9188828409e-15, 0.0000000000e+00) - (-2.6025110118e-02, 0.0000000000e+00) - (9.4347903791e-02, 0.0000000000e+00) - (3.4163853956e-12, 0.0000000000e+00) - (-3.9164243592e-01, 0.0000000000e+00) - (-4.2396413367e-02, 0.0000000000e+00) - (3.4336957449e-01, 0.0000000000e+00) + (-4.8754985571e-07, 0.0000000000e+00) + (7.0300014456e-12, 0.0000000000e+00) + (1.7713570935e-13, 0.0000000000e+00) + (2.3914190527e-14, 0.0000000000e+00) + (4.1972041426e-01, 0.0000000000e+00) + (-7.2002197373e-12, 0.0000000000e+00) + (2.4203350713e-13, 0.0000000000e+00) + (3.5027648482e-14, 0.0000000000e+00) + (2.8730538113e-05, 0.0000000000e+00) + (3.1755384619e-02, 0.0000000000e+00) + (-1.6877789920e-10, 0.0000000000e+00) + (2.9846857176e-13, 0.0000000000e+00) + (9.8842069695e-06, 0.0000000000e+00) + (1.2581829603e-13, 0.0000000000e+00) + (-2.5224266218e-02, 0.0000000000e+00) + (8.6560579984e-02, 0.0000000000e+00) + (-9.5315545393e-13, 0.0000000000e+00) + (-3.8931337443e-01, 0.0000000000e+00) + (-4.1882966824e-02, 0.0000000000e+00) + (3.4036220956e-01, 0.0000000000e+00) (1.0000000000e+00, 0.0000000000e+00) - (2.2344053162e-13, 0.0000000000e+00) + (-1.1943677876e-13, 0.0000000000e+00) (0.0000000000e+00, 0.0000000000e+00) - (-5.2148085685e-09, 0.0000000000e+00) - (-1.0267783752e-14, 0.0000000000e+00) - (1.1927726651e-15, 0.0000000000e+00) - (-1.8665044698e-17, 0.0000000000e+00) - (-5.1718197488e-04, 0.0000000000e+00) - (2.1417612881e-14, 0.0000000000e+00) - (-3.2401303220e-15, 0.0000000000e+00) - (-7.7361251121e-17, 0.0000000000e+00) - (1.6624329713e-07, 0.0000000000e+00) - (1.8826070938e-02, 0.0000000000e+00) - (2.4868513219e-12, 0.0000000000e+00) - (-3.4633595360e-16, 0.0000000000e+00) - (-4.2105360318e-08, 0.0000000000e+00) - (1.4053488026e-16, 0.0000000000e+00) - (1.1469293539e-01, 0.0000000000e+00) - (-3.1137352258e-03, 0.0000000000e+00) - (-8.9747634607e-15, 0.0000000000e+00) - (8.1299463518e-01, 0.0000000000e+00) - (9.5040954767e-02, 0.0000000000e+00) + (-9.1561329949e-10, 0.0000000000e+00) + (1.2836682894e-14, 0.0000000000e+00) + (3.2588421236e-16, 0.0000000000e+00) + (4.3612737680e-17, 0.0000000000e+00) + (5.6623916347e-04, 0.0000000000e+00) + (-1.3051856077e-14, 0.0000000000e+00) + (4.3829287494e-16, 0.0000000000e+00) + (6.4195435363e-17, 0.0000000000e+00) + (6.5966783712e-08, 0.0000000000e+00) + (1.7228118377e-02, 0.0000000000e+00) + (-3.0620808664e-13, 0.0000000000e+00) + (5.4417200830e-16, 0.0000000000e+00) + (1.6983001295e-08, 0.0000000000e+00) + (2.2695959504e-16, 0.0000000000e+00) + (1.1179750398e-01, 0.0000000000e+00) + (-3.6412620165e-02, 0.0000000000e+00) + (-1.7216763296e-15, 0.0000000000e+00) + (8.1417294498e-01, 0.0000000000e+00) + (9.4074762326e-02, 0.0000000000e+00) (-1.0000000000e+00, 0.0000000000e+00) - (2.9256271222e-01, 0.0000000000e+00) - (-5.7395993926e-16, 0.0000000000e+00) + (3.0435750857e-01, 0.0000000000e+00) + (-2.2099057718e-16, 0.0000000000e+00) (0.0000000000e+00, 0.0000000000e+00) - (2.3950541266e-12, 0.0000000000e+00) - (6.0610465737e-18, 0.0000000000e+00) - (-5.9338040247e-19, 0.0000000000e+00) - (1.2742701686e-20, 0.0000000000e+00) - (5.0169717856e-07, 0.0000000000e+00) - (-1.0810701412e-17, 0.0000000000e+00) - (1.6494278532e-18, 0.0000000000e+00) - (4.2539191926e-20, 0.0000000000e+00) - (-6.4075134033e-11, 0.0000000000e+00) - (1.9181672748e-02, 0.0000000000e+00) - (-1.2573288600e-15, 0.0000000000e+00) - (2.1282885404e-19, 0.0000000000e+00) - (2.3634670246e-11, 0.0000000000e+00) - (-2.8800527991e-20, 0.0000000000e+00) - (-2.5325784854e-05, 0.0000000000e+00) - (1.0335479965e-01, 0.0000000000e+00) - (4.5259796369e-18, 0.0000000000e+00) - (8.8648007468e-01, 0.0000000000e+00) - (9.5090618474e-02, 0.0000000000e+00) - (-1.0000000000e+00, 0.0000000000e+00) - (1.1643736689e-01, 0.0000000000e+00) - (2.8857164798e-19, 0.0000000000e+00) + (-2.1252658976e-12, 0.0000000000e+00) + (2.9997960867e-17, 0.0000000000e+00) + (7.6046521855e-19, 0.0000000000e+00) + (1.0190416295e-19, 0.0000000000e+00) + (1.6063656692e-06, 0.0000000000e+00) + (-3.0623052978e-17, 0.0000000000e+00) + (1.0284626209e-18, 0.0000000000e+00) + (1.4987887064e-19, 0.0000000000e+00) + (1.4527553327e-10, 0.0000000000e+00) + (6.4716676613e-02, 0.0000000000e+00) + (-7.1824947090e-16, 0.0000000000e+00) + (1.2731882738e-18, 0.0000000000e+00) + (4.0756474316e-11, 0.0000000000e+00) + (5.3318188926e-19, 0.0000000000e+00) + (1.9226655020e-04, 0.0000000000e+00) + (8.3435360015e-02, 0.0000000000e+00) + (-4.0445417853e-18, 0.0000000000e+00) + (5.7076607079e+00, 0.0000000000e+00) + (6.0466124312e-01, 0.0000000000e+00) + (-6.4573481542e+00, 0.0000000000e+00) + (1.0000000000e+00, 0.0000000000e+00) + (-5.1501093822e-19, 0.0000000000e+00) (0.0000000000e+00, 0.0000000000e+00) - (-5.7714829164e-16, 0.0000000000e+00) - (-1.2757888749e-21, 0.0000000000e+00) - (1.3746710540e-22, 0.0000000000e+00) - (-2.4976712556e-24, 0.0000000000e+00) - (-8.5080480350e-11, 0.0000000000e+00) - (2.4770923808e-21, 0.0000000000e+00) - (-3.7609331693e-22, 0.0000000000e+00) - (-9.2824157200e-24, 0.0000000000e+00) - (1.7296880853e-14, 0.0000000000e+00) - (2.1503220407e-01, 0.0000000000e+00) - (2.8785152320e-19, 0.0000000000e+00) - (-4.3889063322e-23, 0.0000000000e+00) - (-5.1285716129e-15, 0.0000000000e+00) - (1.1636863235e-23, 0.0000000000e+00) - (1.1566649891e-08, 0.0000000000e+00) - (1.8256614252e+00, 0.0000000000e+00) - (-1.0373009605e-21, 0.0000000000e+00) - (-9.2115828305e-05, 0.0000000000e+00) - (-4.3130701745e-02, 0.0000000000e+00) - (8.0216581289e-02, 0.0000000000e+00) + (-1.1449801987e-19, 0.0000000000e+00) + (1.6116767978e-24, 0.0000000000e+00) + (4.0882526275e-26, 0.0000000000e+00) + (5.4744896638e-27, 0.0000000000e+00) + (8.2035866051e-14, 0.0000000000e+00) + (-1.6438720376e-24, 0.0000000000e+00) + (5.5204989011e-26, 0.0000000000e+00) + (8.0550483367e-27, 0.0000000000e+00) + (8.0005286957e-18, 0.0000000000e+00) + (9.9044568532e-02, 0.0000000000e+00) + (-3.8559701260e-23, 0.0000000000e+00) + (6.8391525998e-26, 0.0000000000e+00) + (2.1737385026e-18, 0.0000000000e+00) + (2.8614413826e-26, 0.0000000000e+00) + (1.2538204625e-11, 0.0000000000e+00) + (2.0011366265e-01, 0.0000000000e+00) + (-2.1703294005e-25, 0.0000000000e+00) + (2.2569741649e-07, 0.0000000000e+00) + (-2.7996411497e-01, 0.0000000000e+00) + (1.5510319801e-02, 0.0000000000e+00) (-1.0000000000e+00, 0.0000000000e+00) - (-6.6600537486e-23, 0.0000000000e+00) + (-2.7700702446e-26, 0.0000000000e+00) (0.0000000000e+00, 0.0000000000e+00) - (-5.1393132172e-23, 0.0000000000e+00) - (-1.2223260472e-28, 0.0000000000e+00) - (1.2472127420e-29, 0.0000000000e+00) - (-2.4921386080e-31, 0.0000000000e+00) - (-9.3866206045e-18, 0.0000000000e+00) - (2.2633516268e-28, 0.0000000000e+00) - (-3.4457712577e-29, 0.0000000000e+00) - (-8.7193547804e-31, 0.0000000000e+00) - (1.4534773421e-21, 0.0000000000e+00) - (8.5135632574e-02, 0.0000000000e+00) - (2.6312791437e-26, 0.0000000000e+00) - (-4.2532326447e-30, 0.0000000000e+00) - (-4.8283014269e-22, 0.0000000000e+00) - (8.2614743310e-31, 0.0000000000e+00) - (7.6731079426e-16, 0.0000000000e+00) - (7.4139053519e-08, 0.0000000000e+00) - (-9.4777332249e-29, 0.0000000000e+00) - (-1.6492458843e-11, 0.0000000000e+00) - (-5.3545678111e-01, 0.0000000000e+00) - (5.5321885466e-01, 0.0000000000e+00) + (3.1820220896e-24, 0.0000000000e+00) + (-4.4822630014e-29, 0.0000000000e+00) + (-1.1368321325e-30, 0.0000000000e+00) + (-1.5225091907e-31, 0.0000000000e+00) + (-2.3302085246e-18, 0.0000000000e+00) + (4.5734581436e-29, 0.0000000000e+00) + (-1.5358844780e-30, 0.0000000000e+00) + (-2.2400090484e-31, 0.0000000000e+00) + (-2.2094488310e-22, 0.0000000000e+00) + (-1.8336505872e-02, 0.0000000000e+00) + (1.0727499881e-27, 0.0000000000e+00) + (-1.9022334499e-30, 0.0000000000e+00) + (-6.0615501465e-23, 0.0000000000e+00) + (-7.9613900988e-31, 0.0000000000e+00) + (-3.3135587070e-16, 0.0000000000e+00) + (-4.0953349121e-06, 0.0000000000e+00) + (6.0388698693e-30, 0.0000000000e+00) + (-7.6137983141e-12, 0.0000000000e+00) + (-5.1318295748e-01, 0.0000000000e+00) + (5.3700219722e-01, 0.0000000000e+00) (-1.0000000000e+00, 0.0000000000e+00) - (-6.0503559297e-30, 0.0000000000e+00) + (7.7018454915e-31, 0.0000000000e+00) (0.0000000000e+00, 0.0000000000e+00) - (1.5925410439e-26, 0.0000000000e+00) - (3.6467104870e-32, 0.0000000000e+00) - (-3.8298975648e-33, 0.0000000000e+00) - (7.2843458977e-35, 0.0000000000e+00) - (2.6099600921e-21, 0.0000000000e+00) - (-6.9217406878e-32, 0.0000000000e+00) - (1.0522524455e-32, 0.0000000000e+00) - (2.6275752137e-34, 0.0000000000e+00) - (-4.6503968988e-25, 0.0000000000e+00) - (7.0547384077e-01, 0.0000000000e+00) - (-8.0451698383e-30, 0.0000000000e+00) - (1.2615689245e-33, 0.0000000000e+00) - (1.4541717981e-25, 0.0000000000e+00) - (-2.8943968584e-34, 0.0000000000e+00) - (-2.8606052566e-19, 0.0000000000e+00) - (-4.4874685909e-11, 0.0000000000e+00) - (2.8983937471e-32, 0.0000000000e+00) - (3.6960608889e-15, 0.0000000000e+00) - (-4.0375031261e-01, 0.0000000000e+00) - (-7.6027396744e-05, 0.0000000000e+00) + (-3.0016757256e-30, 0.0000000000e+00) + (4.2271228779e-35, 0.0000000000e+00) + (1.0721795130e-36, 0.0000000000e+00) + (1.4358369440e-37, 0.0000000000e+00) + (2.1843856809e-24, 0.0000000000e+00) + (-4.3127531539e-35, 0.0000000000e+00) + (1.4483264552e-36, 0.0000000000e+00) + (2.1125642296e-37, 0.0000000000e+00) + (2.0888971586e-28, 0.0000000000e+00) + (2.6690976502e-01, 0.0000000000e+00) + (-1.0116078010e-33, 0.0000000000e+00) + (1.7939220813e-36, 0.0000000000e+00) + (5.7121848499e-29, 0.0000000000e+00) + (7.5074727477e-37, 0.0000000000e+00) + (3.1917019460e-22, 0.0000000000e+00) + (4.6850421700e-12, 0.0000000000e+00) + (-5.6944209627e-36, 0.0000000000e+00) + (6.8236414835e-18, 0.0000000000e+00) + (-1.8768267994e-01, 0.0000000000e+00) + (-3.7256047478e-07, 0.0000000000e+00) (-1.0000000000e+00, 0.0000000000e+00) - (1.8571774028e-33, 0.0000000000e+00) + (-7.2641542152e-37, 0.0000000000e+00) (0.0000000000e+00, 0.0000000000e+00) - (-6.0678926774e-31, 0.0000000000e+00) - (-1.4169528127e-36, 0.0000000000e+00) - (1.4656289987e-37, 0.0000000000e+00) - (-2.8609740925e-39, 0.0000000000e+00) - (-1.0544668056e-25, 0.0000000000e+00) - (2.6548603568e-36, 0.0000000000e+00) - (-4.0390229421e-37, 0.0000000000e+00) - (-1.0156762175e-38, 0.0000000000e+00) - (1.7431137997e-29, 0.0000000000e+00) - (-1.2074567704e-05, 0.0000000000e+00) - (3.0860942824e-34, 0.0000000000e+00) - (-4.9167573890e-38, 0.0000000000e+00) - (-5.6218529923e-30, 0.0000000000e+00) - (1.0390962127e-38, 0.0000000000e+00) - (9.9265428167e-24, 0.0000000000e+00) - (1.2543626869e-15, 0.0000000000e+00) - (-1.1117200938e-36, 0.0000000000e+00) - (-1.7207310405e-19, 0.0000000000e+00) - (4.0649505983e-01, 0.0000000000e+00) - (5.7414371702e-09, 0.0000000000e+00) + (-9.6182923408e-36, 0.0000000000e+00) + (1.3545969898e-40, 0.0000000000e+00) + (3.4357922411e-42, 0.0000000000e+00) + (4.6011907912e-43, 0.0000000000e+00) + (7.0149307011e-30, 0.0000000000e+00) + (-1.3820825954e-40, 0.0000000000e+00) + (4.6413693014e-42, 0.0000000000e+00) + (6.7697347650e-43, 0.0000000000e+00) + (6.6890988107e-34, 0.0000000000e+00) + (6.2942207941e-07, 0.0000000000e+00) + (-3.2418314470e-39, 0.0000000000e+00) + (5.7487353105e-42, 0.0000000000e+00) + (1.8309566104e-34, 0.0000000000e+00) + (2.4058823969e-42, 0.0000000000e+00) + (1.0166318570e-27, 0.0000000000e+00) + (1.4267499404e-17, 0.0000000000e+00) + (-1.8248787474e-41, 0.0000000000e+00) + (2.2332304570e-23, 0.0000000000e+00) + (1.6308597476e+00, 0.0000000000e+00) + (-1.4482519248e-12, 0.0000000000e+00) (1.0000000000e+00, 0.0000000000e+00) - (-7.1077864462e-38, 0.0000000000e+00) + (-2.3277660593e-42, 0.0000000000e+00) (0.0000000000e+00, 0.0000000000e+00) - (1.7429871531e-38, 0.0000000000e+00) - (4.0299642797e-44, 0.0000000000e+00) - (-4.2011538443e-45, 0.0000000000e+00) - (8.0929885677e-47, 0.0000000000e+00) - (2.9401789627e-33, 0.0000000000e+00) - (-7.6007466657e-44, 0.0000000000e+00) - (1.1559025412e-44, 0.0000000000e+00) - (2.8962383491e-46, 0.0000000000e+00) - (-5.0497381269e-37, 0.0000000000e+00) - (6.8332733435e-13, 0.0000000000e+00) - (-8.8348684842e-42, 0.0000000000e+00) - (1.3962470057e-45, 0.0000000000e+00) - (1.6030963360e-37, 0.0000000000e+00) - (-3.0764647662e-46, 0.0000000000e+00) - (-3.0008748926e-31, 0.0000000000e+00) - (-4.3710100161e-23, 0.0000000000e+00) - (3.1827439438e-44, 0.0000000000e+00) - (4.4668164702e-27, 0.0000000000e+00) - (-5.2094124217e-09, 0.0000000000e+00) - (-1.2011747378e-16, 0.0000000000e+00) + (-1.0564710711e-44, 0.0000000000e+00) + (1.4878505497e-49, 0.0000000000e+00) + (3.7737939829e-51, 0.0000000000e+00) + (5.0538142875e-52, 0.0000000000e+00) + (7.7002227238e-39, 0.0000000000e+00) + (-1.5180271617e-49, 0.0000000000e+00) + (5.0979025865e-51, 0.0000000000e+00) + (7.4357021991e-52, 0.0000000000e+00) + (7.3488764173e-43, 0.0000000000e+00) + (8.3848023031e-16, 0.0000000000e+00) + (-3.5607077321e-48, 0.0000000000e+00) + (6.3142353114e-51, 0.0000000000e+00) + (2.0109223541e-43, 0.0000000000e+00) + (2.6425288751e-51, 0.0000000000e+00) + (1.1190325769e-36, 0.0000000000e+00) + (1.6004626254e-26, 0.0000000000e+00) + (-2.0043707060e-50, 0.0000000000e+00) + (2.4381742756e-32, 0.0000000000e+00) + (1.3181821526e-09, 0.0000000000e+00) + (-1.5116733884e-21, 0.0000000000e+00) (1.0000000000e+00, 0.0000000000e+00) - (2.0373903795e-45, 0.0000000000e+00) + (-2.5567739155e-51, 0.0000000000e+00) (0.0000000000e+00, 0.0000000000e+00) (0.0000000000e+00, 0.0000000000e+00) @@ -1222,45 +1222,45 @@ The eigenvectors are: (0.0000000000e+00, 0.0000000000e+00) (1.0000000000e+00, 0.0000000000e+00) -No. 0,REAL part: Left 1.093870e+03, Right 0.000000e+00, Diff. 1.093870e+03 +No. 0,REAL part: Left -2.242124e+03, Right 0.000000e+00, Diff. -2.242124e+03 No. 0,IM part: Left 0.000000e+00, Right 0.000000e+00, Diff 0.000000e+00 -No. 1,REAL part: Left 9.287575e+03, Right 0.000000e+00, Diff. 9.287575e+03 +No. 1,REAL part: Left -1.841803e+04, Right 0.000000e+00, Diff. -1.841803e+04 No. 1,IM part: Left 0.000000e+00, Right 0.000000e+00, Diff 0.000000e+00 -No. 2,REAL part: Left 1.066987e+01, Right 0.000000e+00, Diff. 1.066987e+01 +No. 2,REAL part: Left 9.260330e+01, Right 0.000000e+00, Diff. 9.260330e+01 No. 2,IM part: Left 0.000000e+00, Right 0.000000e+00, Diff 0.000000e+00 -No. 3,REAL part: Left 2.032161e+02, Right 0.000000e+00, Diff. 2.032161e+02 +No. 3,REAL part: Left 2.027440e+02, Right 0.000000e+00, Diff. 2.027440e+02 No. 3,IM part: Left 0.000000e+00, Right 0.000000e+00, Diff 0.000000e+00 -No. 4,REAL part: Left -1.455210e+02, Right 0.000000e+00, Diff. -1.455210e+02 +No. 4,REAL part: Left -5.327622e+01, Right 0.000000e+00, Diff. -5.327622e+01 No. 4,IM part: Left 0.000000e+00, Right 0.000000e+00, Diff 0.000000e+00 -No. 5,REAL part: Left -1.133907e+04, Right 0.000000e+00, Diff. -1.133907e+04 +No. 5,REAL part: Left -1.139813e+04, Right 0.000000e+00, Diff. -1.139813e+04 No. 5,IM part: Left 0.000000e+00, Right 0.000000e+00, Diff 0.000000e+00 -No. 6,REAL part: Left 2.865820e+03, Right 0.000000e+00, Diff. 2.865820e+03 +No. 6,REAL part: Left 2.558260e+05, Right 0.000000e+00, Diff. 2.558260e+05 No. 6,IM part: Left 0.000000e+00, Right 0.000000e+00, Diff 0.000000e+00 -No. 7,REAL part: Left 1.903385e+02, Right 0.000000e+00, Diff. 1.903385e+02 +No. 7,REAL part: Left 1.864621e+03, Right 0.000000e+00, Diff. 1.864621e+03 No. 7,IM part: Left 0.000000e+00, Right 0.000000e+00, Diff 0.000000e+00 -No. 8,REAL part: Left 1.420231e+02, Right 0.000000e+00, Diff. 1.420231e+02 +No. 8,REAL part: Left -4.112580e+01, Right 0.000000e+00, Diff. -4.112580e+01 No. 8,IM part: Left 0.000000e+00, Right 0.000000e+00, Diff 0.000000e+00 -No. 9,REAL part: Left -1.048041e+04, Right 0.000000e+00, Diff. -1.048041e+04 +No. 9,REAL part: Left 7.492033e+03, Right 0.000000e+00, Diff. 7.492033e+03 No. 9,IM part: Left 0.000000e+00, Right 0.000000e+00, Diff 0.000000e+00 -No. 10,REAL part: Left -4.252020e+00, Right 0.000000e+00, Diff. -4.252020e+00 +No. 10,REAL part: Left -5.259469e+00, Right 0.000000e+00, Diff. -5.259469e+00 No. 10,IM part: Left 0.000000e+00, Right 0.000000e+00, Diff 0.000000e+00 -No. 11,REAL part: Left 1.225886e+00, Right 0.000000e+00, Diff. 1.225886e+00 +No. 11,REAL part: Left 1.013224e+00, Right 0.000000e+00, Diff. 1.013224e+00 No. 11,IM part: Left 0.000000e+00, Right 0.000000e+00, Diff 0.000000e+00 -No. 12,REAL part: Left -9.080365e+01, Right 0.000000e+00, Diff. -9.080365e+01 +No. 12,REAL part: Left -8.670782e+01, Right 0.000000e+00, Diff. -8.670782e+01 No. 12,IM part: Left 0.000000e+00, Right 0.000000e+00, Diff 0.000000e+00 -No. 13,REAL part: Left -6.488728e-03, Right 0.000000e+00, Diff. -6.488728e-03 +No. 13,REAL part: Left 6.654727e-03, Right 0.000000e+00, Diff. 6.654727e-03 No. 13,IM part: Left 0.000000e+00, Right 0.000000e+00, Diff 0.000000e+00 -No. 14,REAL part: Left 5.205818e-02, Right 0.000000e+00, Diff. 5.205818e-02 +No. 14,REAL part: Left 5.045625e-02, Right 0.000000e+00, Diff. 5.045625e-02 No. 14,IM part: Left 0.000000e+00, Right 0.000000e+00, Diff 0.000000e+00 -No. 15,REAL part: Left 1.165834e-01, Right 0.000000e+00, Diff. 1.165834e-01 +No. 15,REAL part: Left 1.188337e-01, Right 0.000000e+00, Diff. 1.188337e-01 No. 15,IM part: Left 0.000000e+00, Right 0.000000e+00, Diff 0.000000e+00 -No. 16,REAL part: Left 1.488376e-02, Right 0.000000e+00, Diff. 1.488376e-02 +No. 16,REAL part: Left 8.358925e-03, Right 0.000000e+00, Diff. 8.358925e-03 No. 16,IM part: Left 0.000000e+00, Right 0.000000e+00, Diff 0.000000e+00 -No. 17,REAL part: Left 9.236319e-05, Right 0.000000e+00, Diff. 9.236319e-05 +No. 17,REAL part: Left -2.017426e-07, Right 0.000000e+00, Diff. -2.017426e-07 No. 17,IM part: Left 0.000000e+00, Right 0.000000e+00, Diff 0.000000e+00 -No. 18,REAL part: Left 5.356206e-01, Right 0.000000e+00, Diff. 5.356206e-01 +No. 18,REAL part: Left 5.133400e-01, Right 0.000000e+00, Diff. 5.133400e-01 No. 18,IM part: Left 0.000000e+00, Right 0.000000e+00, Diff 0.000000e+00 -No. 19,REAL part: Left -4.037503e-01, Right 0.000000e+00, Diff. -4.037503e-01 +No. 19,REAL part: Left -1.876827e-01, Right 0.000000e+00, Diff. -1.876827e-01 No. 19,IM part: Left 0.000000e+00, Right 0.000000e+00, Diff 0.000000e+00 No. 20,REAL part: Left -8.018837e-04, Right 0.000000e+00, Diff. -8.018837e-04 No. 20,IM part: Left 0.000000e+00, Right 0.000000e+00, Diff 0.000000e+00 diff --git a/test/expected/gtf.des.m2/model.c b/test/expected/gtf.des.m2/model.c index 286c39a..9d4dde9 100644 --- a/test/expected/gtf.des.m2/model.c +++ b/test/expected/gtf.des.m2/model.c @@ -718,14 +718,14 @@ void calc_jac(double S[equa], double tk, double R[equa], double Jac[equa+1][equa CeIII=(1.660000e-04-CeIV); Br2MA=0.000000e+00; Jac[1][1]=tk*((((((-3.060000e-04+(-1.000000e+00*((2.000000e+06 -*Br_m)*1.290000e+00)))-(-((3.300000e+00*HOBr))))+(-2.000000e+00 +*Br_m)*1.290000e+00)))-(3.300000e+00*HOBr))+(-2.000000e+00 *(3.000000e+03*(HBrO2*2.000000e+00))))+(-1.000000e+00 -*((3.300000e+01*BrO3_m)*1.290000e+00)))+(-((7.000000e+03 -*CeIV)))))-(1+4*R[0]); +*((3.300000e+01*BrO3_m)*1.290000e+00)))-(7.000000e+03 +*CeIV)))-(1+4*R[0]); Jac[1][2]=tk*(((-1.000000e+00*((2.000000e+06*HBrO2)*1.290000e+00 ))+((2.000000e+00*BrO3_m)*1.664100e+00))); Jac[1][3]=tk*((((-1.000000e+00*(-((2.000000e-05*(HOBr*2.000000e+00 -)))))-(-((3.300000e+00*HBrO2))))+(-2.000000e+00*(-(((7.500000e-09 +)))))-(3.300000e+00*HBrO2))+(-2.000000e+00*(-(((7.500000e-09 *BrO3_m)*1.290000e+00)))))); Jac[1][4]=tk*(0.000000e+00); Jac[1][5]=tk*(((((2.000000e+00*Br_m)*1.664100e+00)+(-2.000000e+00 @@ -787,24 +787,24 @@ Jac[2][22]=tk*((((1.000000e+09*Br)+(1.000000e+07*BrMA))+(1.500000e+08 *Br2))); Jac[2][23]=tk*(0.000000e+00); Jac[3][1]=tk*((((2.000000e+00*((2.000000e+06*Br_m)*1.290000e+00 -))+(-((3.300000e+00*HOBr))))+(3.000000e+03*(HBrO2*2.000000e+00 +))-(3.300000e+00*HOBr))+(3.000000e+03*(HBrO2*2.000000e+00 )))); Jac[3][2]=tk*((((-1.000000e+00*((2.300000e+09*HOBr)*1.290000e+00 ))+(2.000000e+00*((2.000000e+06*HBrO2)*1.290000e+00 )))+((2.000000e+00*BrO3_m)*1.664100e+00))); Jac[3][3]=tk*((((((((((((((-3.060000e-04+(-1.000000e+00*((2.300000e+09 *Br_m)*1.290000e+00)))+(2.000000e+00*(-((2.000000e-05 -*(HOBr*2.000000e+00))))))+(-((3.300000e+00*HBrO2))))-(-((( -7.500000e-09*BrO3_m)*1.290000e+00))))+(-1.000000e+00* -(8.200000e+00*MA)))+(-1.000000e+00*(1.000000e-01*BrMA -)))+(-1.000000e+00*(5.000000e+00*TTA)))+(-1.000000e+00 -*(1.400000e+02*MOA)))+(-1.000000e+00*(1.400000e+02*OA -)))+(-1.000000e+00*(1.000000e+07*MAR)))+(-1.000000e+00 -*(1.000000e+07*TTAR)))+(-1.000000e+00*(1.000000e+05* -BrMAR)))+(-1.000000e+00*(2.000000e+07*FAR))))-(1+4*R[2]); +*(HOBr*2.000000e+00))))))-(3.300000e+00*HBrO2))-((7.500000e-09 +*BrO3_m)*1.290000e+00))+(-1.000000e+00*(8.200000e+00 +*MA)))+(-1.000000e+00*(1.000000e-01*BrMA)))+(-1.000000e+00 +*(5.000000e+00*TTA)))+(-1.000000e+00*(1.400000e+02*MOA +)))+(-1.000000e+00*(1.400000e+02*OA)))+(-1.000000e+00 +*(1.000000e+07*MAR)))+(-1.000000e+00*(1.000000e+07*TTAR +)))+(-1.000000e+00*(1.000000e+05*BrMAR)))+(-1.000000e+00 +*(2.000000e+07*FAR))))-(1+4*R[2]); Jac[3][4]=tk*(2.000000e+00); -Jac[3][5]=tk*((((2.000000e+00*Br_m)*1.664100e+00)-(-(((7.500000e-09 -*HOBr)*1.290000e+00))))); +Jac[3][5]=tk*((((2.000000e+00*Br_m)*1.664100e+00)-((7.500000e-09 +*HOBr)*1.290000e+00))); Jac[3][6]=tk*(0.000000e+00); Jac[3][7]=tk*(0.000000e+00); Jac[3][8]=tk*(0.000000e+00); @@ -854,12 +854,12 @@ Jac[5][1]=tk*((((-1.000000e+00*(-((3.300000e+00*HOBr))))+(3.000000e+03 *BrO3_m)*1.290000e+00)))); Jac[5][2]=tk*((-1.000000e+00*((2.000000e+00*BrO3_m)*1.664100e+00 ))); -Jac[5][3]=tk*(((-1.000000e+00*(-((3.300000e+00*HBrO2))))-(-((( -7.500000e-09*BrO3_m)*1.290000e+00))))); +Jac[5][3]=tk*(((-1.000000e+00*(-((3.300000e+00*HBrO2))))-((7.500000e-09 +*BrO3_m)*1.290000e+00))); Jac[5][4]=tk*(0.000000e+00); Jac[5][5]=tk*(((((((((-3.060000e-04+(-1.000000e+00*((2.000000e+00 -*Br_m)*1.664100e+00)))-(-(((7.500000e-09*HOBr)*1.290000e+00 -))))+(-1.000000e+00*((3.300000e+01*HBrO2)*1.290000e+00 +*Br_m)*1.664100e+00)))-((7.500000e-09*HOBr)*1.290000e+00 +))+(-1.000000e+00*((3.300000e+01*HBrO2)*1.290000e+00 )))+(-1.000000e+00*((1.600000e-05*OA)*1.290000e+00)) )+(-1.000000e+00*((4.000000e+01*MAR)*1.290000e+00))) +(-1.000000e+00*((4.000000e+01*TTAR)*1.290000e+00))) @@ -1037,8 +1037,8 @@ Jac[10][8]=tk*((-1.000000e+00*(1.000000e+05*MA))); Jac[10][9]=tk*((-1.000000e+00*((2.300000e-01*MA)-((-1.700000e+04 *MAR)*1.290000e+00)))); Jac[10][10]=tk*((((((-3.306000e-03+(-1.000000e+00*(8.200000e+00 -*HOBr)))+(-1.000000e+00*(2.300000e-01*CeIV)))-(-((1.000000e+05 -*TTAR))))+(-((5.000000e+02*BrMAR))))+(-1.000000e+00*(1.000000e+05 +*HOBr)))+(-1.000000e+00*(2.300000e-01*CeIV)))-(1.000000e+05 +*TTAR))-(5.000000e+02*BrMAR))+(-1.000000e+00*(1.000000e+05 *Br))))-(1+4*R[9]); Jac[10][11]=tk*(2.000000e+02); Jac[10][12]=tk*(((((((-1.000000e+00*(-(((1.700000e+04*(1.660000e-04 @@ -1047,8 +1047,8 @@ Jac[10][12]=tk*(((((((-1.000000e+00*(-(((1.700000e+04*(1.660000e-04 )+(2.000000e+09*FAR))+(1.000000e+05*TTA))+(1.000000e+05 *BrMA))); Jac[10][13]=tk*((1.000000e+05*MAR)); -Jac[10][14]=tk*((((1.801802e+07*MAR)*5.550000e+01)+(-((5.000000e+02 -*MA))))); +Jac[10][14]=tk*((((1.801802e+07*MAR)*5.550000e+01)-(5.000000e+02 +*MA))); Jac[10][15]=tk*(0.000000e+00); Jac[10][16]=tk*((1.000000e+05*MAR)); Jac[10][17]=tk*((-((1.000000e+05*MA)))); @@ -1098,8 +1098,8 @@ Jac[12][10]=tk*(((((2.300000e-01*CeIV)+(-1.000000e+00*(-((1.000000e+05 *TTAR)))))+(-1.000000e+00*(-((5.000000e+02*BrMAR)))))+(1.000000e+05 *Br))); Jac[12][11]=tk*(0.000000e+00); -Jac[12][12]=tk*(((((((((((((-3.060000e-04+(-(((1.700000e+04*(1.660000e-04 --CeIV))*1.290000e+00))))+(-1.000000e+00*((1.801802e+07 +Jac[12][12]=tk*(((((((((((((-3.060000e-04-((1.700000e+04*(1.660000e-04 +-CeIV))*1.290000e+00))+(-1.000000e+00*((1.801802e+07 *BrMAR)*5.550000e+01)))+(-2.000000e+00*((5.765766e+07 *(MAR*2.000000e+00))*5.550000e+01)))+(-1.000000e+00* ((1.801802e+07*TTAR)*5.550000e+01)))+(-1.000000e+00* @@ -1184,7 +1184,7 @@ Jac[14][14]=tk*(((((((((((((-3.060000e-04+(-1.000000e+00*(1.000000e+09 )*5.550000e+01)))+(-1.000000e+00*((1.801802e+05*CeIV )*5.550000e+01)))+(-1.000000e+00*((9.009009e+07*BrO2 )*5.550000e+01)))+(-1.000000e+00*(5.000000e+08*FAR)) -)+(-((5.000000e+02*MA))))-(-((5.000000e+03*TTA))))+(-1.000000e+00 +)-(5.000000e+02*MA))-(5.000000e+03*TTA))+(-1.000000e+00 *(1.000000e+06*Br2)))+(-1.000000e+00*(1.000000e+05*HOBr )))+(-1.000000e+00*((4.000000e+01*BrO3_m)*1.290000e+00 ))))-(1+4*R[13]); @@ -1239,12 +1239,12 @@ Jac[16][12]=tk*(((((((5.765766e+07*(MAR*2.000000e+00))*5.550000e+01 )+(1.000000e+07*HOBr))+((4.000000e+01*BrO3_m)*1.290000e+00 ))+(-1.000000e+00*(1.000000e+05*TTA)))); Jac[16][13]=tk*((2.000000e+05*TTAR)); -Jac[16][14]=tk*((((1.801802e+07*TTAR)*5.550000e+01)+(-((5.000000e+03 -*TTA))))); +Jac[16][14]=tk*((((1.801802e+07*TTAR)*5.550000e+01)-(5.000000e+03 +*TTA))); Jac[16][15]=tk*(1.000000e+00); Jac[16][16]=tk*((((((-3.060000e-04+(-1.000000e+00*(5.000000e+00 *HOBr)))+(-1.000000e+00*(6.600000e-01*CeIV)))+(-1.000000e+00 -*(1.000000e+05*MAR)))+(-((5.000000e+03*BrMAR))))+(-1.000000e+00 +*(1.000000e+05*MAR)))-(5.000000e+03*BrMAR))+(-1.000000e+00 *(1.000000e+06*Br))))-(1+4*R[15]); Jac[16][17]=tk*((((((((-1.000000e+00*(-(((1.700000e+04*(1.660000e-04 -CeIV))*1.290000e+00))))+((1.801802e+07*BrMAR)*5.550000e+01 @@ -1281,13 +1281,13 @@ Jac[17][15]=tk*(0.000000e+00); Jac[17][16]=tk*(((((6.600000e-01*CeIV)+(1.000000e+05*MAR))+( -1.000000e+00*(-((5.000000e+03*BrMAR)))))+(1.000000e+06 *Br))); -Jac[17][17]=tk*(((((((((((((-3.060000e-04-(-(((1.700000e+04*(1.660000e-04 --CeIV))*1.290000e+00))))+(-1.000000e+00*((1.801802e+07 +Jac[17][17]=tk*(((((((((((((-3.060000e-04-((1.700000e+04*(1.660000e-04 +-CeIV))*1.290000e+00))+(-1.000000e+00*((1.801802e+07 *BrMAR)*5.550000e+01)))+(-1.000000e+00*((1.801802e+07 *MAR)*5.550000e+01)))+(-2.000000e+00*(1.000000e+09*( TTAR*2.000000e+00))))+(-1.000000e+00*(2.000000e+09*FAR )))+(-1.000000e+00*(1.000000e+09*Br)))+(-1.000000e+00 -*(5.000000e+09*BrO2)))+(-((1.000000e+05*MA))))+(-1.000000e+00 +*(5.000000e+09*BrO2)))-(1.000000e+05*MA))+(-1.000000e+00 *(2.000000e+05*BrMA)))+(-1.000000e+00*(1.000000e+08* Br2)))+(-1.000000e+00*(1.000000e+07*HOBr)))+(-1.000000e+00 *((4.000000e+01*BrO3_m)*1.290000e+00))))-(1+4*R[16]); @@ -1880,14 +1880,14 @@ CO2=S[22]; CeIII=(1.660000e-04-CeIV); Br2MA=0.000000e+00; Jac[0][0]=(((((-3.060000e-04+(-1.000000e+00*((2.000000e+06 -*Br_m)*1.290000e+00)))-(-((3.300000e+00*HOBr))))+(-2.000000e+00 +*Br_m)*1.290000e+00)))-(3.300000e+00*HOBr))+(-2.000000e+00 *(3.000000e+03*(HBrO2*2.000000e+00))))+(-1.000000e+00 -*((3.300000e+01*BrO3_m)*1.290000e+00)))+(-((7.000000e+03 -*CeIV)))); +*((3.300000e+01*BrO3_m)*1.290000e+00)))-(7.000000e+03 +*CeIV)); Jac[0][1]=((-1.000000e+00*((2.000000e+06*HBrO2)*1.290000e+00 ))+((2.000000e+00*BrO3_m)*1.664100e+00)); Jac[0][2]=(((-1.000000e+00*(-((2.000000e-05*(HOBr*2.000000e+00 -)))))-(-((3.300000e+00*HBrO2))))+(-2.000000e+00*(-(((7.500000e-09 +)))))-(3.300000e+00*HBrO2))+(-2.000000e+00*(-(((7.500000e-09 *BrO3_m)*1.290000e+00))))); Jac[0][3]=0.000000e+00; Jac[0][4]=((((2.000000e+00*Br_m)*1.664100e+00)+(-2.000000e+00 @@ -1949,24 +1949,24 @@ Jac[1][21]=(((1.000000e+09*Br)+(1.000000e+07*BrMA))+(1.500000e+08 *Br2)); Jac[1][22]=0.000000e+00; Jac[2][0]=(((2.000000e+00*((2.000000e+06*Br_m)*1.290000e+00 -))+(-((3.300000e+00*HOBr))))+(3.000000e+03*(HBrO2*2.000000e+00 +))-(3.300000e+00*HOBr))+(3.000000e+03*(HBrO2*2.000000e+00 ))); Jac[2][1]=(((-1.000000e+00*((2.300000e+09*HOBr)*1.290000e+00 ))+(2.000000e+00*((2.000000e+06*HBrO2)*1.290000e+00 )))+((2.000000e+00*BrO3_m)*1.664100e+00)); Jac[2][2]=(((((((((((((-3.060000e-04+(-1.000000e+00*((2.300000e+09 *Br_m)*1.290000e+00)))+(2.000000e+00*(-((2.000000e-05 -*(HOBr*2.000000e+00))))))+(-((3.300000e+00*HBrO2))))-(-((( -7.500000e-09*BrO3_m)*1.290000e+00))))+(-1.000000e+00* -(8.200000e+00*MA)))+(-1.000000e+00*(1.000000e-01*BrMA -)))+(-1.000000e+00*(5.000000e+00*TTA)))+(-1.000000e+00 -*(1.400000e+02*MOA)))+(-1.000000e+00*(1.400000e+02*OA -)))+(-1.000000e+00*(1.000000e+07*MAR)))+(-1.000000e+00 -*(1.000000e+07*TTAR)))+(-1.000000e+00*(1.000000e+05* -BrMAR)))+(-1.000000e+00*(2.000000e+07*FAR))); +*(HOBr*2.000000e+00))))))-(3.300000e+00*HBrO2))-((7.500000e-09 +*BrO3_m)*1.290000e+00))+(-1.000000e+00*(8.200000e+00 +*MA)))+(-1.000000e+00*(1.000000e-01*BrMA)))+(-1.000000e+00 +*(5.000000e+00*TTA)))+(-1.000000e+00*(1.400000e+02*MOA +)))+(-1.000000e+00*(1.400000e+02*OA)))+(-1.000000e+00 +*(1.000000e+07*MAR)))+(-1.000000e+00*(1.000000e+07*TTAR +)))+(-1.000000e+00*(1.000000e+05*BrMAR)))+(-1.000000e+00 +*(2.000000e+07*FAR))); Jac[2][3]=2.000000e+00; -Jac[2][4]=(((2.000000e+00*Br_m)*1.664100e+00)-(-(((7.500000e-09 -*HOBr)*1.290000e+00)))); +Jac[2][4]=(((2.000000e+00*Br_m)*1.664100e+00)-((7.500000e-09 +*HOBr)*1.290000e+00)); Jac[2][5]=0.000000e+00; Jac[2][6]=0.000000e+00; Jac[2][7]=0.000000e+00; @@ -2016,12 +2016,12 @@ Jac[4][0]=(((-1.000000e+00*(-((3.300000e+00*HOBr))))+(3.000000e+03 *BrO3_m)*1.290000e+00))); Jac[4][1]=(-1.000000e+00*((2.000000e+00*BrO3_m)*1.664100e+00 )); -Jac[4][2]=((-1.000000e+00*(-((3.300000e+00*HBrO2))))-(-((( -7.500000e-09*BrO3_m)*1.290000e+00)))); +Jac[4][2]=((-1.000000e+00*(-((3.300000e+00*HBrO2))))-((7.500000e-09 +*BrO3_m)*1.290000e+00)); Jac[4][3]=0.000000e+00; Jac[4][4]=((((((((-3.060000e-04+(-1.000000e+00*((2.000000e+00 -*Br_m)*1.664100e+00)))-(-(((7.500000e-09*HOBr)*1.290000e+00 -))))+(-1.000000e+00*((3.300000e+01*HBrO2)*1.290000e+00 +*Br_m)*1.664100e+00)))-((7.500000e-09*HOBr)*1.290000e+00 +))+(-1.000000e+00*((3.300000e+01*HBrO2)*1.290000e+00 )))+(-1.000000e+00*((1.600000e-05*OA)*1.290000e+00)) )+(-1.000000e+00*((4.000000e+01*MAR)*1.290000e+00))) +(-1.000000e+00*((4.000000e+01*TTAR)*1.290000e+00))) @@ -2199,8 +2199,8 @@ Jac[9][7]=(-1.000000e+00*(1.000000e+05*MA)); Jac[9][8]=(-1.000000e+00*((2.300000e-01*MA)-((-1.700000e+04 *MAR)*1.290000e+00))); Jac[9][9]=(((((-3.306000e-03+(-1.000000e+00*(8.200000e+00 -*HOBr)))+(-1.000000e+00*(2.300000e-01*CeIV)))-(-((1.000000e+05 -*TTAR))))+(-((5.000000e+02*BrMAR))))+(-1.000000e+00*(1.000000e+05 +*HOBr)))+(-1.000000e+00*(2.300000e-01*CeIV)))-(1.000000e+05 +*TTAR))-(5.000000e+02*BrMAR))+(-1.000000e+00*(1.000000e+05 *Br))); Jac[9][10]=2.000000e+02; Jac[9][11]=((((((-1.000000e+00*(-(((1.700000e+04*(1.660000e-04 @@ -2209,8 +2209,8 @@ Jac[9][11]=((((((-1.000000e+00*(-(((1.700000e+04*(1.660000e-04 )+(2.000000e+09*FAR))+(1.000000e+05*TTA))+(1.000000e+05 *BrMA)); Jac[9][12]=(1.000000e+05*MAR); -Jac[9][13]=(((1.801802e+07*MAR)*5.550000e+01)+(-((5.000000e+02 -*MA)))); +Jac[9][13]=(((1.801802e+07*MAR)*5.550000e+01)-(5.000000e+02 +*MA)); Jac[9][14]=0.000000e+00; Jac[9][15]=(1.000000e+05*MAR); Jac[9][16]=(-((1.000000e+05*MA))); @@ -2260,8 +2260,8 @@ Jac[11][9]=((((2.300000e-01*CeIV)+(-1.000000e+00*(-((1.000000e+05 *TTAR)))))+(-1.000000e+00*(-((5.000000e+02*BrMAR)))))+(1.000000e+05 *Br)); Jac[11][10]=0.000000e+00; -Jac[11][11]=((((((((((((-3.060000e-04+(-(((1.700000e+04*(1.660000e-04 --CeIV))*1.290000e+00))))+(-1.000000e+00*((1.801802e+07 +Jac[11][11]=((((((((((((-3.060000e-04-((1.700000e+04*(1.660000e-04 +-CeIV))*1.290000e+00))+(-1.000000e+00*((1.801802e+07 *BrMAR)*5.550000e+01)))+(-2.000000e+00*((5.765766e+07 *(MAR*2.000000e+00))*5.550000e+01)))+(-1.000000e+00* ((1.801802e+07*TTAR)*5.550000e+01)))+(-1.000000e+00* @@ -2346,7 +2346,7 @@ Jac[13][13]=((((((((((((-3.060000e-04+(-1.000000e+00*(1.000000e+09 )*5.550000e+01)))+(-1.000000e+00*((1.801802e+05*CeIV )*5.550000e+01)))+(-1.000000e+00*((9.009009e+07*BrO2 )*5.550000e+01)))+(-1.000000e+00*(5.000000e+08*FAR)) -)+(-((5.000000e+02*MA))))-(-((5.000000e+03*TTA))))+(-1.000000e+00 +)-(5.000000e+02*MA))-(5.000000e+03*TTA))+(-1.000000e+00 *(1.000000e+06*Br2)))+(-1.000000e+00*(1.000000e+05*HOBr )))+(-1.000000e+00*((4.000000e+01*BrO3_m)*1.290000e+00 ))); @@ -2401,12 +2401,12 @@ Jac[15][11]=((((((5.765766e+07*(MAR*2.000000e+00))*5.550000e+01 )+(1.000000e+07*HOBr))+((4.000000e+01*BrO3_m)*1.290000e+00 ))+(-1.000000e+00*(1.000000e+05*TTA))); Jac[15][12]=(2.000000e+05*TTAR); -Jac[15][13]=(((1.801802e+07*TTAR)*5.550000e+01)+(-((5.000000e+03 -*TTA)))); +Jac[15][13]=(((1.801802e+07*TTAR)*5.550000e+01)-(5.000000e+03 +*TTA)); Jac[15][14]=1.000000e+00; Jac[15][15]=(((((-3.060000e-04+(-1.000000e+00*(5.000000e+00 *HOBr)))+(-1.000000e+00*(6.600000e-01*CeIV)))+(-1.000000e+00 -*(1.000000e+05*MAR)))+(-((5.000000e+03*BrMAR))))+(-1.000000e+00 +*(1.000000e+05*MAR)))-(5.000000e+03*BrMAR))+(-1.000000e+00 *(1.000000e+06*Br))); Jac[15][16]=(((((((-1.000000e+00*(-(((1.700000e+04*(1.660000e-04 -CeIV))*1.290000e+00))))+((1.801802e+07*BrMAR)*5.550000e+01 @@ -2443,13 +2443,13 @@ Jac[16][14]=0.000000e+00; Jac[16][15]=((((6.600000e-01*CeIV)+(1.000000e+05*MAR))+( -1.000000e+00*(-((5.000000e+03*BrMAR)))))+(1.000000e+06 *Br)); -Jac[16][16]=((((((((((((-3.060000e-04-(-(((1.700000e+04*(1.660000e-04 --CeIV))*1.290000e+00))))+(-1.000000e+00*((1.801802e+07 +Jac[16][16]=((((((((((((-3.060000e-04-((1.700000e+04*(1.660000e-04 +-CeIV))*1.290000e+00))+(-1.000000e+00*((1.801802e+07 *BrMAR)*5.550000e+01)))+(-1.000000e+00*((1.801802e+07 *MAR)*5.550000e+01)))+(-2.000000e+00*(1.000000e+09*( TTAR*2.000000e+00))))+(-1.000000e+00*(2.000000e+09*FAR )))+(-1.000000e+00*(1.000000e+09*Br)))+(-1.000000e+00 -*(5.000000e+09*BrO2)))+(-((1.000000e+05*MA))))+(-1.000000e+00 +*(5.000000e+09*BrO2)))-(1.000000e+05*MA))+(-1.000000e+00 *(2.000000e+05*BrMA)))+(-1.000000e+00*(1.000000e+08* Br2)))+(-1.000000e+00*(1.000000e+07*HOBr)))+(-1.000000e+00 *((4.000000e+01*BrO3_m)*1.290000e+00))); diff --git a/test/expected/gtf.des.m3/model.c b/test/expected/gtf.des.m3/model.c index 35b9db3..680e504 100644 --- a/test/expected/gtf.des.m3/model.c +++ b/test/expected/gtf.des.m3/model.c @@ -331,14 +331,14 @@ OA=S_[20]; FAR=S_[21]; CO2=S_[22]; jacobi_matx[0][0]=(((((-3.060000e-04+(-1.000000e+00*((2.000000e+06 -*Br_m)*1.290000e+00)))-(-((3.300000e+00*HOBr))))+(-2.000000e+00 +*Br_m)*1.290000e+00)))-(3.300000e+00*HOBr))+(-2.000000e+00 *(3.000000e+03*(HBrO2*2.000000e+00))))+(-1.000000e+00 -*((3.300000e+01*BrO3_m)*1.290000e+00)))+(-((7.000000e+03 -*CeIV)))); +*((3.300000e+01*BrO3_m)*1.290000e+00)))-(7.000000e+03 +*CeIV)); jacobi_matx[0][1]=((-1.000000e+00*((2.000000e+06*HBrO2)*1.290000e+00 ))+((2.000000e+00*BrO3_m)*1.664100e+00)); jacobi_matx[0][2]=(((-1.000000e+00*(-((2.000000e-05*(HOBr*2.000000e+00 -)))))-(-((3.300000e+00*HBrO2))))+(-2.000000e+00*(-(((7.500000e-09 +)))))-(3.300000e+00*HBrO2))+(-2.000000e+00*(-(((7.500000e-09 *BrO3_m)*1.290000e+00))))); jacobi_matx[0][4]=((((2.000000e+00*Br_m)*1.664100e+00)+(-2.000000e+00 *(-(((7.500000e-09*HOBr)*1.290000e+00)))))+(-1.000000e+00 @@ -376,23 +376,23 @@ jacobi_matx[1][20]=(2.000000e+03*Br); jacobi_matx[1][21]=(((1.000000e+09*Br)+(1.000000e+07*BrMA))+(1.500000e+08 *Br2)); jacobi_matx[2][0]=(((2.000000e+00*((2.000000e+06*Br_m)*1.290000e+00 -))+(-((3.300000e+00*HOBr))))+(3.000000e+03*(HBrO2*2.000000e+00 +))-(3.300000e+00*HOBr))+(3.000000e+03*(HBrO2*2.000000e+00 ))); jacobi_matx[2][1]=(((-1.000000e+00*((2.300000e+09*HOBr)*1.290000e+00 ))+(2.000000e+00*((2.000000e+06*HBrO2)*1.290000e+00 )))+((2.000000e+00*BrO3_m)*1.664100e+00)); jacobi_matx[2][2]=(((((((((((((-3.060000e-04+(-1.000000e+00*((2.300000e+09 *Br_m)*1.290000e+00)))+(2.000000e+00*(-((2.000000e-05 -*(HOBr*2.000000e+00))))))+(-((3.300000e+00*HBrO2))))-(-((( -7.500000e-09*BrO3_m)*1.290000e+00))))+(-1.000000e+00* -(8.200000e+00*MA)))+(-1.000000e+00*(1.000000e-01*BrMA -)))+(-1.000000e+00*(5.000000e+00*TTA)))+(-1.000000e+00 -*(1.400000e+02*MOA)))+(-1.000000e+00*(1.400000e+02*OA -)))+(-1.000000e+00*(1.000000e+07*MAR)))+(-1.000000e+00 -*(1.000000e+07*TTAR)))+(-1.000000e+00*(1.000000e+05* -BrMAR)))+(-1.000000e+00*(2.000000e+07*FAR))); -jacobi_matx[2][4]=(((2.000000e+00*Br_m)*1.664100e+00)-(-(((7.500000e-09 -*HOBr)*1.290000e+00)))); +*(HOBr*2.000000e+00))))))-(3.300000e+00*HBrO2))-((7.500000e-09 +*BrO3_m)*1.290000e+00))+(-1.000000e+00*(8.200000e+00 +*MA)))+(-1.000000e+00*(1.000000e-01*BrMA)))+(-1.000000e+00 +*(5.000000e+00*TTA)))+(-1.000000e+00*(1.400000e+02*MOA +)))+(-1.000000e+00*(1.400000e+02*OA)))+(-1.000000e+00 +*(1.000000e+07*MAR)))+(-1.000000e+00*(1.000000e+07*TTAR +)))+(-1.000000e+00*(1.000000e+05*BrMAR)))+(-1.000000e+00 +*(2.000000e+07*FAR))); +jacobi_matx[2][4]=(((2.000000e+00*Br_m)*1.664100e+00)-((7.500000e-09 +*HOBr)*1.290000e+00)); jacobi_matx[2][9]=(-1.000000e+00*(8.200000e+00*HOBr)); jacobi_matx[2][11]=(-1.000000e+00*(1.000000e+07*HOBr)); jacobi_matx[2][12]=(-1.000000e+00*(1.000000e-01*HOBr)); @@ -419,11 +419,11 @@ jacobi_matx[4][0]=(((-1.000000e+00*(-((3.300000e+00*HOBr))))+(3.000000e+03 *BrO3_m)*1.290000e+00))); jacobi_matx[4][1]=(-1.000000e+00*((2.000000e+00*BrO3_m)*1.664100e+00 )); -jacobi_matx[4][2]=((-1.000000e+00*(-((3.300000e+00*HBrO2))))-(-((( -7.500000e-09*BrO3_m)*1.290000e+00)))); +jacobi_matx[4][2]=((-1.000000e+00*(-((3.300000e+00*HBrO2))))-((7.500000e-09 +*BrO3_m)*1.290000e+00)); jacobi_matx[4][4]=((((((((-3.060000e-04+(-1.000000e+00*((2.000000e+00 -*Br_m)*1.664100e+00)))-(-(((7.500000e-09*HOBr)*1.290000e+00 -))))+(-1.000000e+00*((3.300000e+01*HBrO2)*1.290000e+00 +*Br_m)*1.664100e+00)))-((7.500000e-09*HOBr)*1.290000e+00 +))+(-1.000000e+00*((3.300000e+01*HBrO2)*1.290000e+00 )))+(-1.000000e+00*((1.600000e-05*OA)*1.290000e+00)) )+(-1.000000e+00*((4.000000e+01*MAR)*1.290000e+00))) +(-1.000000e+00*((4.000000e+01*TTAR)*1.290000e+00))) @@ -526,8 +526,8 @@ jacobi_matx[9][7]=(-1.000000e+00*(1.000000e+05*MA)); jacobi_matx[9][8]=(-1.000000e+00*((2.300000e-01*MA)-((-1.700000e+04 *MAR)*1.290000e+00))); jacobi_matx[9][9]=(((((-3.306000e-03+(-1.000000e+00*(8.200000e+00 -*HOBr)))+(-1.000000e+00*(2.300000e-01*CeIV)))-(-((1.000000e+05 -*TTAR))))+(-((5.000000e+02*BrMAR))))+(-1.000000e+00*(1.000000e+05 +*HOBr)))+(-1.000000e+00*(2.300000e-01*CeIV)))-(1.000000e+05 +*TTAR))-(5.000000e+02*BrMAR))+(-1.000000e+00*(1.000000e+05 *Br))); jacobi_matx[9][11]=((((((-1.000000e+00*(-(((1.700000e+04*(1.660000e-04 -CeIV))*1.290000e+00))))+((1.801802e+07*BrMAR)*5.550000e+01 @@ -535,8 +535,8 @@ jacobi_matx[9][11]=((((((-1.000000e+00*(-(((1.700000e+04*(1.660000e-04 )+(2.000000e+09*FAR))+(1.000000e+05*TTA))+(1.000000e+05 *BrMA)); jacobi_matx[9][12]=(1.000000e+05*MAR); -jacobi_matx[9][13]=(((1.801802e+07*MAR)*5.550000e+01)+(-((5.000000e+02 -*MA)))); +jacobi_matx[9][13]=(((1.801802e+07*MAR)*5.550000e+01)-(5.000000e+02 +*MA)); jacobi_matx[9][15]=(1.000000e+05*MAR); jacobi_matx[9][16]=(-((1.000000e+05*MA))); jacobi_matx[9][21]=(2.000000e+09*MAR); @@ -555,8 +555,8 @@ jacobi_matx[11][8]=((2.300000e-01*MA)-((-1.700000e+04*MAR)*1.290000e+00 jacobi_matx[11][9]=((((2.300000e-01*CeIV)+(-1.000000e+00*(-((1.000000e+05 *TTAR)))))+(-1.000000e+00*(-((5.000000e+02*BrMAR)))))+(1.000000e+05 *Br)); -jacobi_matx[11][11]=((((((((((((-3.060000e-04+(-(((1.700000e+04*(1.660000e-04 --CeIV))*1.290000e+00))))+(-1.000000e+00*((1.801802e+07 +jacobi_matx[11][11]=((((((((((((-3.060000e-04-((1.700000e+04*(1.660000e-04 +-CeIV))*1.290000e+00))+(-1.000000e+00*((1.801802e+07 *BrMAR)*5.550000e+01)))+(-2.000000e+00*((5.765766e+07 *(MAR*2.000000e+00))*5.550000e+01)))+(-1.000000e+00* ((1.801802e+07*TTAR)*5.550000e+01)))+(-1.000000e+00* @@ -620,7 +620,7 @@ jacobi_matx[13][13]=((((((((((((-3.060000e-04+(-1.000000e+00*(1.000000e+09 )*5.550000e+01)))+(-1.000000e+00*((1.801802e+05*CeIV )*5.550000e+01)))+(-1.000000e+00*((9.009009e+07*BrO2 )*5.550000e+01)))+(-1.000000e+00*(5.000000e+08*FAR)) -)+(-((5.000000e+02*MA))))-(-((5.000000e+03*TTA))))+(-1.000000e+00 +)-(5.000000e+02*MA))-(5.000000e+03*TTA))+(-1.000000e+00 *(1.000000e+06*Br2)))+(-1.000000e+00*(1.000000e+05*HOBr )))+(-1.000000e+00*((4.000000e+01*BrO3_m)*1.290000e+00 ))); @@ -642,11 +642,11 @@ jacobi_matx[15][11]=((((((5.765766e+07*(MAR*2.000000e+00))*5.550000e+01 )+(1.000000e+07*HOBr))+((4.000000e+01*BrO3_m)*1.290000e+00 ))+(-1.000000e+00*(1.000000e+05*TTA))); jacobi_matx[15][12]=(2.000000e+05*TTAR); -jacobi_matx[15][13]=(((1.801802e+07*TTAR)*5.550000e+01)+(-((5.000000e+03 -*TTA)))); +jacobi_matx[15][13]=(((1.801802e+07*TTAR)*5.550000e+01)-(5.000000e+03 +*TTA)); jacobi_matx[15][15]=(((((-3.060000e-04+(-1.000000e+00*(5.000000e+00 *HOBr)))+(-1.000000e+00*(6.600000e-01*CeIV)))+(-1.000000e+00 -*(1.000000e+05*MAR)))+(-((5.000000e+03*BrMAR))))+(-1.000000e+00 +*(1.000000e+05*MAR)))-(5.000000e+03*BrMAR))+(-1.000000e+00 *(1.000000e+06*Br))); jacobi_matx[15][16]=(((((((-1.000000e+00*(-(((1.700000e+04*(1.660000e-04 -CeIV))*1.290000e+00))))+((1.801802e+07*BrMAR)*5.550000e+01 @@ -673,13 +673,13 @@ jacobi_matx[16][13]=((-1.000000e+00*((1.801802e+07*TTAR)*5.550000e+01 jacobi_matx[16][15]=((((6.600000e-01*CeIV)+(1.000000e+05*MAR))+( -1.000000e+00*(-((5.000000e+03*BrMAR)))))+(1.000000e+06 *Br)); -jacobi_matx[16][16]=((((((((((((-3.060000e-04-(-(((1.700000e+04*(1.660000e-04 --CeIV))*1.290000e+00))))+(-1.000000e+00*((1.801802e+07 +jacobi_matx[16][16]=((((((((((((-3.060000e-04-((1.700000e+04*(1.660000e-04 +-CeIV))*1.290000e+00))+(-1.000000e+00*((1.801802e+07 *BrMAR)*5.550000e+01)))+(-1.000000e+00*((1.801802e+07 *MAR)*5.550000e+01)))+(-2.000000e+00*(1.000000e+09*( TTAR*2.000000e+00))))+(-1.000000e+00*(2.000000e+09*FAR )))+(-1.000000e+00*(1.000000e+09*Br)))+(-1.000000e+00 -*(5.000000e+09*BrO2)))+(-((1.000000e+05*MA))))+(-1.000000e+00 +*(5.000000e+09*BrO2)))-(1.000000e+05*MA))+(-1.000000e+00 *(2.000000e+05*BrMA)))+(-1.000000e+00*(1.000000e+08* Br2)))+(-1.000000e+00*(1.000000e+07*HOBr)))+(-1.000000e+00 *((4.000000e+01*BrO3_m)*1.290000e+00))); diff --git a/test/expected/gtf.des.m3/sim.last b/test/expected/gtf.des.m3/sim.last index 632ee8d..4f6740f 100644 --- a/test/expected/gtf.des.m3/sim.last +++ b/test/expected/gtf.des.m3/sim.last @@ -1 +1 @@ -2.000000e+02 3.265494e-07 9.811265e-08 8.476925e-10 3.699502e-08 8.949695e-03 4.577973e-12 1.266126e-08 2.891193e-14 1.001654e-06 1.590887e-01 2.385484e-06 1.935003e-10 6.655621e-03 8.021671e-10 5.795259e-09 3.254434e-03 4.521222e-12 5.498601e-08 2.579850e-10 3.277583e-03 2.279340e-05 5.022981e-13 2.890820e-05 +2.000000e+02 3.264647e-07 9.811812e-08 8.474732e-10 3.698756e-08 8.949695e-03 4.575786e-12 1.265812e-08 2.890340e-14 1.001438e-06 1.590887e-01 2.385485e-06 1.934885e-10 6.655620e-03 8.021970e-10 5.793365e-09 3.254434e-03 4.521005e-12 5.497500e-08 2.579076e-10 3.277584e-03 2.279325e-05 5.021896e-13 2.890805e-05 diff --git a/test/expected/hbry1.des.m2/model.c b/test/expected/hbry1.des.m2/model.c index 3b2434a..479c4d4 100644 --- a/test/expected/hbry1.des.m2/model.c +++ b/test/expected/hbry1.des.m2/model.c @@ -104,11 +104,11 @@ Jac[1][4]=tk*((-1.000000e+00*(-((5.131501e-05*Br))))); Jac[1][5]=tk*((-1.000000e+00*(4.190137e+10*Br2))); Jac[2][1]=tk*((4.411877e-03+(4.190137e+10*H))); Jac[2][2]=tk*((((2.000000e+00*(-((8.800000e+07*(Br*2.000000e+00 -)))))+(-1.000000e+00*(1.794836e+04*H2)))-(-((5.131501e-05 -*HBr)))))-(1+4*R[1]); +)))))+(-1.000000e+00*(1.794836e+04*H2)))-(5.131501e-05 +*HBr)))-(1+4*R[1]); Jac[2][3]=tk*((-1.000000e+00*(1.794836e+04*Br))); -Jac[2][4]=tk*(((-1.000000e+00*(-((4.739617e+07*H))))-(-((5.131501e-05 -*Br))))); +Jac[2][4]=tk*(((-1.000000e+00*(-((4.739617e+07*H))))-(5.131501e-05 +*Br))); Jac[2][5]=tk*(((-1.000000e+00*(-((4.739617e+07*HBr))))+(4.190137e+10 *Br2))); Jac[3][1]=tk*(0.000000e+00); @@ -117,9 +117,9 @@ Jac[3][3]=tk*((-1.000000e+00*(1.794836e+04*Br)))-(1+4*R[2]); Jac[3][4]=tk*((-1.000000e+00*(-((4.739617e+07*H))))); Jac[3][5]=tk*((-1.000000e+00*(-((4.739617e+07*HBr))))); Jac[4][1]=tk*((4.190137e+10*H)); -Jac[4][2]=tk*(((1.794836e+04*H2)-(-((5.131501e-05*HBr))))); +Jac[4][2]=tk*(((1.794836e+04*H2)-(5.131501e-05*HBr))); Jac[4][3]=tk*((1.794836e+04*Br)); -Jac[4][4]=tk*(((-((4.739617e+07*H)))-(-((5.131501e-05*Br)))))-(1+4*R[3]); +Jac[4][4]=tk*(((-((4.739617e+07*H)))-(5.131501e-05*Br)))-(1+4*R[3]); Jac[4][5]=tk*(((-((4.739617e+07*HBr)))+(4.190137e+10*Br2))); Jac[5][1]=tk*((-1.000000e+00*(4.190137e+10*H))); Jac[5][2]=tk*(((1.794836e+04*H2)+(-1.000000e+00*(-((5.131501e-05 @@ -194,11 +194,11 @@ Jac[0][3]=(-1.000000e+00*(-((5.131501e-05*Br)))); Jac[0][4]=(-1.000000e+00*(4.190137e+10*Br2)); Jac[1][0]=(4.411877e-03+(4.190137e+10*H)); Jac[1][1]=(((2.000000e+00*(-((8.800000e+07*(Br*2.000000e+00 -)))))+(-1.000000e+00*(1.794836e+04*H2)))-(-((5.131501e-05 -*HBr)))); +)))))+(-1.000000e+00*(1.794836e+04*H2)))-(5.131501e-05 +*HBr)); Jac[1][2]=(-1.000000e+00*(1.794836e+04*Br)); -Jac[1][3]=((-1.000000e+00*(-((4.739617e+07*H))))-(-((5.131501e-05 -*Br)))); +Jac[1][3]=((-1.000000e+00*(-((4.739617e+07*H))))-(5.131501e-05 +*Br)); Jac[1][4]=((-1.000000e+00*(-((4.739617e+07*HBr))))+(4.190137e+10 *Br2)); Jac[2][0]=0.000000e+00; @@ -207,9 +207,9 @@ Jac[2][2]=(-1.000000e+00*(1.794836e+04*Br)); Jac[2][3]=(-1.000000e+00*(-((4.739617e+07*H)))); Jac[2][4]=(-1.000000e+00*(-((4.739617e+07*HBr)))); Jac[3][0]=(4.190137e+10*H); -Jac[3][1]=((1.794836e+04*H2)-(-((5.131501e-05*HBr)))); +Jac[3][1]=((1.794836e+04*H2)-(5.131501e-05*HBr)); Jac[3][2]=(1.794836e+04*Br); -Jac[3][3]=((-((4.739617e+07*H)))-(-((5.131501e-05*Br)))); +Jac[3][3]=((-((4.739617e+07*H)))-(5.131501e-05*Br)); Jac[3][4]=((-((4.739617e+07*HBr)))+(4.190137e+10*Br2)); Jac[4][0]=(-1.000000e+00*(4.190137e+10*H)); Jac[4][1]=((1.794836e+04*H2)+(-1.000000e+00*(-((5.131501e-05 diff --git a/test/expected/hbry1.des.m3/model.c b/test/expected/hbry1.des.m3/model.c index 19c3132..42bc464 100644 --- a/test/expected/hbry1.des.m3/model.c +++ b/test/expected/hbry1.des.m3/model.c @@ -54,11 +54,11 @@ jacobi_matx[0][3]=(-1.000000e+00*(-((5.131501e-05*Br)))); jacobi_matx[0][4]=(-1.000000e+00*(4.190137e+10*Br2)); jacobi_matx[1][0]=(4.411877e-03+(4.190137e+10*H)); jacobi_matx[1][1]=(((2.000000e+00*(-((8.800000e+07*(Br*2.000000e+00 -)))))+(-1.000000e+00*(1.794836e+04*H2)))-(-((5.131501e-05 -*HBr)))); +)))))+(-1.000000e+00*(1.794836e+04*H2)))-(5.131501e-05 +*HBr)); jacobi_matx[1][2]=(-1.000000e+00*(1.794836e+04*Br)); -jacobi_matx[1][3]=((-1.000000e+00*(-((4.739617e+07*H))))-(-((5.131501e-05 -*Br)))); +jacobi_matx[1][3]=((-1.000000e+00*(-((4.739617e+07*H))))-(5.131501e-05 +*Br)); jacobi_matx[1][4]=((-1.000000e+00*(-((4.739617e+07*HBr))))+(4.190137e+10 *Br2)); jacobi_matx[2][1]=(-1.000000e+00*(1.794836e+04*H2)); @@ -66,9 +66,9 @@ jacobi_matx[2][2]=(-1.000000e+00*(1.794836e+04*Br)); jacobi_matx[2][3]=(-1.000000e+00*(-((4.739617e+07*H)))); jacobi_matx[2][4]=(-1.000000e+00*(-((4.739617e+07*HBr)))); jacobi_matx[3][0]=(4.190137e+10*H); -jacobi_matx[3][1]=((1.794836e+04*H2)-(-((5.131501e-05*HBr)))); +jacobi_matx[3][1]=((1.794836e+04*H2)-(5.131501e-05*HBr)); jacobi_matx[3][2]=(1.794836e+04*Br); -jacobi_matx[3][3]=((-((4.739617e+07*H)))-(-((5.131501e-05*Br)))); +jacobi_matx[3][3]=((-((4.739617e+07*H)))-(5.131501e-05*Br)); jacobi_matx[3][4]=((-((4.739617e+07*HBr)))+(4.190137e+10*Br2)); jacobi_matx[4][0]=(-1.000000e+00*(4.190137e+10*H)); jacobi_matx[4][1]=((1.794836e+04*H2)+(-1.000000e+00*(-((5.131501e-05 diff --git a/test/expected/hbry1.des.m3/sim.last b/test/expected/hbry1.des.m3/sim.last index 1588b9f..f57a759 100644 --- a/test/expected/hbry1.des.m3/sim.last +++ b/test/expected/hbry1.des.m3/sim.last @@ -1 +1 @@ -2.000000e+03 6.897804e-05 4.158373e-08 6.899884e-05 1.862002e-03 1.728976e-14 +2.000000e+03 6.897804e-05 4.158356e-08 6.899884e-05 1.862002e-03 1.728968e-14 diff --git a/test/expected/real.des.m2/model.c b/test/expected/real.des.m2/model.c index a3a3123..657d9a1 100644 --- a/test/expected/real.des.m2/model.c +++ b/test/expected/real.des.m2/model.c @@ -231,9 +231,9 @@ void calc_jac(double S[equa], double tk, double R[equa], double Jac[equa+1][equa H_p=2.600000e-01; H2O=5.550000e+01; CeIII=(8.333330e-04-CeIV); -Jac[1][1]=tk*(((((((-1.000000e+00*(2.770000e-03*Br_m))-(-((3.200000e+00 -*HOBr))))+(-1.000000e+00*((2.000000e+06*Br_m)*2.600000e-01 -)))+-8.580000e-01)+(-((7.000000e+03*CeIV))))+(-2.000000e+00 +Jac[1][1]=tk*(((((((-1.000000e+00*(2.770000e-03*Br_m))-(3.200000e+00 +*HOBr))+(-1.000000e+00*((2.000000e+06*Br_m)*2.600000e-01 +)))+-8.580000e-01)-(7.000000e+03*CeIV))+(-2.000000e+00 *(3.000000e+03*(HBrO2*2.000000e+00)))))-(1+4*R[0]); Jac[1][2]=tk*((((-1.000000e+00*(2.770000e-03*HBrO2))+1.352000e-02 )+(-1.000000e+00*((2.000000e+06*HBrO2)*2.600000e-01) @@ -286,10 +286,10 @@ Jac[4][2]=tk*(((1.352000e-02+(2.000000e+00*((2.000000e+06 *HBrO2)*2.600000e-01)))+(-1.000000e+00*((2.307692e+09 *HOBr)*2.600000e-01)))); Jac[4][3]=tk*(0.000000e+00); -Jac[4][4]=tk*(((((((-2.770000e-03+(-((3.200000e+00*HBrO2))))+ -(-1.000000e+00*((2.307692e+09*Br_m)*2.600000e-01)))+ -(-1.000000e+00*(8.200000e+00*MA)))+-8.000000e-02)+-1.400000e-01 -)+(-1.000000e+00*(1.000000e+07*MAR))))-(1+4*R[3]); +Jac[4][4]=tk*(((((((-2.770000e-03-(3.200000e+00*HBrO2))+(-1.000000e+00 +*((2.307692e+09*Br_m)*2.600000e-01)))+(-1.000000e+00 +*(8.200000e+00*MA)))+-8.000000e-02)+-1.400000e-01)+(-1.000000e+00 +*(1.000000e+07*MAR))))-(1+4*R[3]); Jac[4][5]=tk*(0.000000e+00); Jac[4][6]=tk*(2.000000e+00); Jac[4][7]=tk*(0.000000e+00); @@ -489,9 +489,9 @@ MA=S[8]; H_p=2.600000e-01; H2O=5.550000e+01; CeIII=(8.333330e-04-CeIV); -Jac[0][0]=((((((-1.000000e+00*(2.770000e-03*Br_m))-(-((3.200000e+00 -*HOBr))))+(-1.000000e+00*((2.000000e+06*Br_m)*2.600000e-01 -)))+-8.580000e-01)+(-((7.000000e+03*CeIV))))+(-2.000000e+00 +Jac[0][0]=((((((-1.000000e+00*(2.770000e-03*Br_m))-(3.200000e+00 +*HOBr))+(-1.000000e+00*((2.000000e+06*Br_m)*2.600000e-01 +)))+-8.580000e-01)-(7.000000e+03*CeIV))+(-2.000000e+00 *(3.000000e+03*(HBrO2*2.000000e+00)))); Jac[0][1]=(((-1.000000e+00*(2.770000e-03*HBrO2))+1.352000e-02 )+(-1.000000e+00*((2.000000e+06*HBrO2)*2.600000e-01) @@ -544,10 +544,10 @@ Jac[3][1]=((1.352000e-02+(2.000000e+00*((2.000000e+06 *HBrO2)*2.600000e-01)))+(-1.000000e+00*((2.307692e+09 *HOBr)*2.600000e-01))); Jac[3][2]=0.000000e+00; -Jac[3][3]=((((((-2.770000e-03+(-((3.200000e+00*HBrO2))))+ -(-1.000000e+00*((2.307692e+09*Br_m)*2.600000e-01)))+ -(-1.000000e+00*(8.200000e+00*MA)))+-8.000000e-02)+-1.400000e-01 -)+(-1.000000e+00*(1.000000e+07*MAR))); +Jac[3][3]=((((((-2.770000e-03-(3.200000e+00*HBrO2))+(-1.000000e+00 +*((2.307692e+09*Br_m)*2.600000e-01)))+(-1.000000e+00 +*(8.200000e+00*MA)))+-8.000000e-02)+-1.400000e-01)+(-1.000000e+00 +*(1.000000e+07*MAR))); Jac[3][4]=0.000000e+00; Jac[3][5]=2.000000e+00; Jac[3][6]=0.000000e+00; diff --git a/test/expected/real.des.m3/model.c b/test/expected/real.des.m3/model.c index 9c46ab2..390def4 100644 --- a/test/expected/real.des.m3/model.c +++ b/test/expected/real.des.m3/model.c @@ -97,9 +97,9 @@ Br2=S_[5]; BrMA=S_[6]; MAR=S_[7]; MA=S_[8]; -jacobi_matx[0][0]=((((((-1.000000e+00*(2.770000e-03*Br_m))-(-((3.200000e+00 -*HOBr))))+(-1.000000e+00*((2.000000e+06*Br_m)*2.600000e-01 -)))+-8.580000e-01)+(-((7.000000e+03*CeIV))))+(-2.000000e+00 +jacobi_matx[0][0]=((((((-1.000000e+00*(2.770000e-03*Br_m))-(3.200000e+00 +*HOBr))+(-1.000000e+00*((2.000000e+06*Br_m)*2.600000e-01 +)))+-8.580000e-01)-(7.000000e+03*CeIV))+(-2.000000e+00 *(3.000000e+03*(HBrO2*2.000000e+00)))); jacobi_matx[0][1]=(((-1.000000e+00*(2.770000e-03*HBrO2))+1.352000e-02 )+(-1.000000e+00*((2.000000e+06*HBrO2)*2.600000e-01) @@ -142,10 +142,10 @@ jacobi_matx[3][0]=(((-((3.200000e+00*HOBr)))+(2.000000e+00*((2.000000e+06 jacobi_matx[3][1]=((1.352000e-02+(2.000000e+00*((2.000000e+06 *HBrO2)*2.600000e-01)))+(-1.000000e+00*((2.307692e+09 *HOBr)*2.600000e-01))); -jacobi_matx[3][3]=((((((-2.770000e-03+(-((3.200000e+00*HBrO2))))+ -(-1.000000e+00*((2.307692e+09*Br_m)*2.600000e-01)))+ -(-1.000000e+00*(8.200000e+00*MA)))+-8.000000e-02)+-1.400000e-01 -)+(-1.000000e+00*(1.000000e+07*MAR))); +jacobi_matx[3][3]=((((((-2.770000e-03-(3.200000e+00*HBrO2))+(-1.000000e+00 +*((2.307692e+09*Br_m)*2.600000e-01)))+(-1.000000e+00 +*(8.200000e+00*MA)))+-8.000000e-02)+-1.400000e-01)+(-1.000000e+00 +*(1.000000e+07*MAR))); jacobi_matx[3][7]=(-1.000000e+00*(1.000000e+07*HOBr)); jacobi_matx[3][8]=(-1.000000e+00*(8.200000e+00*HOBr)); jacobi_matx[4][0]=(1.716000e+00+(-1.000000e+00*(-((7.000000e+03 diff --git a/test/expected/shn90.des.m1/stdout b/test/expected/shn90.des.m1/stdout index 5b4f4b5..fb6622d 100644 --- a/test/expected/shn90.des.m1/stdout +++ b/test/expected/shn90.des.m1/stdout @@ -54,80 +54,80 @@ Reac. no. 13. Foreward: 3.035200e-08. Eigenvector no. 1. Real. Flow in reaction no. 0.: FW: 1.958176e-05 -Flow in reaction no. 1.: FW: -8.500652e-06 +Flow in reaction no. 1.: FW: -8.500653e-06 Flow in reaction no. 2.: FW: 3.323600e-05 Flow in reaction no. 3.: FW: 1.675807e-05 -Flow in reaction no. 4.: FW: -2.358635e-05 +Flow in reaction no. 4.: FW: -2.358634e-05 Flow in reaction no. 5.: FW: -6.138394e-03 , RV: 4.648942e-07 Flow in reaction no. 6.: FW: 3.354628e-01 , RV: 4.372548e-12 Flow in reaction no. 7.: FW: 2.969433e-01 , RV: -3.009111e-01 -Flow in reaction no. 8.: FW: -4.695107e+00 , RV: 1.921616e-03 -Flow in reaction no. 9.: FW: 1.230194e-04 , RV: 6.050573e-11 +Flow in reaction no. 8.: FW: -4.695107e+00 , RV: 1.921615e-03 +Flow in reaction no. 9.: FW: 1.230194e-04 , RV: 6.050574e-11 Flow in reaction no. 10.: FW: 2.918000e-02 Flow in reaction no. 11.: FW: 7.800000e-02 Flow in reaction no. 12.: FW: 4.033716e-02 -Flow in reaction no. 13.: FW: 7.059002e-02 +Flow in reaction no. 13.: FW: 7.059003e-02 Eigenvector no. 2. Real. -Flow in reaction no. 0.: FW: 4.287256e-06 -Flow in reaction no. 1.: FW: 2.226526e-05 +Flow in reaction no. 0.: FW: 4.287236e-06 +Flow in reaction no. 1.: FW: 2.226514e-05 Flow in reaction no. 2.: FW: 3.323600e-05 -Flow in reaction no. 3.: FW: -6.049530e-05 -Flow in reaction no. 4.: FW: 2.338254e-06 -Flow in reaction no. 5.: FW: 1.607794e-02 , RV: -1.132034e-07 -Flow in reaction no. 6.: FW: 1.492319e-01 , RV: -1.578455e-11 -Flow in reaction no. 7.: FW: 6.501315e-02 , RV: 2.983111e-02 -Flow in reaction no. 8.: FW: 4.650142e-01 , RV: 6.626305e-04 -Flow in reaction no. 9.: FW: 2.693402e-05 , RV: -2.184209e-10 +Flow in reaction no. 3.: FW: -6.049510e-05 +Flow in reaction no. 4.: FW: 2.338242e-06 +Flow in reaction no. 5.: FW: 1.607785e-02 , RV: -1.132032e-07 +Flow in reaction no. 6.: FW: 1.492311e-01 , RV: -1.578450e-11 +Flow in reaction no. 7.: FW: 6.501285e-02 , RV: 2.983095e-02 +Flow in reaction no. 8.: FW: 4.650118e-01 , RV: 6.626288e-04 +Flow in reaction no. 9.: FW: 2.693390e-05 , RV: -2.184202e-10 Flow in reaction no. 10.: FW: 2.918000e-02 Flow in reaction no. 11.: FW: 7.800000e-02 -Flow in reaction no. 12.: FW: -1.456139e-01 -Flow in reaction no. 13.: FW: -2.548243e-01 +Flow in reaction no. 12.: FW: -1.456134e-01 +Flow in reaction no. 13.: FW: -2.548235e-01 Eigenvector no. 3. Real. -Flow in reaction no. 0.: FW: -3.743612e-06 -Flow in reaction no. 1.: FW: 3.303626e-05 +Flow in reaction no. 0.: FW: -3.748575e-06 +Flow in reaction no. 1.: FW: 3.310912e-05 Flow in reaction no. 2.: FW: 3.323600e-05 -Flow in reaction no. 3.: FW: -4.481750e-05 -Flow in reaction no. 4.: FW: -3.881020e-06 -Flow in reaction no. 5.: FW: 2.385576e-02 , RV: -2.283080e-07 -Flow in reaction no. 6.: FW: 3.453444e-02 , RV: -1.169387e-11 -Flow in reaction no. 7.: FW: -5.676918e-02 , RV: -4.951348e-02 -Flow in reaction no. 8.: FW: -7.728916e-01 , RV: 1.560192e-06 -Flow in reaction no. 9.: FW: -2.351866e-05 , RV: -1.618155e-10 +Flow in reaction no. 3.: FW: -4.488060e-05 +Flow in reaction no. 4.: FW: -3.886234e-06 +Flow in reaction no. 5.: FW: 2.390838e-02 , RV: -2.286230e-07 +Flow in reaction no. 6.: FW: 3.467153e-02 , RV: -1.171033e-11 +Flow in reaction no. 7.: FW: -5.684444e-02 , RV: -4.958001e-02 +Flow in reaction no. 8.: FW: -7.739295e-01 , RV: 1.151663e-06 +Flow in reaction no. 9.: FW: -2.354984e-05 , RV: -1.620433e-10 Flow in reaction no. 10.: FW: 2.918000e-02 Flow in reaction no. 11.: FW: 7.800000e-02 -Flow in reaction no. 12.: FW: -1.078770e-01 -Flow in reaction no. 13.: FW: -1.887847e-01 +Flow in reaction no. 12.: FW: -1.080289e-01 +Flow in reaction no. 13.: FW: -1.890505e-01 Eigenvector no. 4. Real. -Flow in reaction no. 0.: FW: 1.061678e-08 -Flow in reaction no. 1.: FW: -1.040169e-08 +Flow in reaction no. 0.: FW: 1.068531e-08 +Flow in reaction no. 1.: FW: -6.059303e-09 Flow in reaction no. 2.: FW: 3.323600e-05 -Flow in reaction no. 3.: FW: 4.973791e-07 -Flow in reaction no. 4.: FW: 1.778879e-08 -Flow in reaction no. 5.: FW: -7.511147e-06 , RV: 1.888122e-09 -Flow in reaction no. 6.: FW: 1.636839e-04 , RV: 1.297771e-13 -Flow in reaction no. 7.: FW: 1.609958e-04 , RV: 2.269468e-04 -Flow in reaction no. 8.: FW: 3.140742e-03 , RV: 3.105939e-04 -Flow in reaction no. 9.: FW: 6.669825e-08 , RV: 1.795809e-12 +Flow in reaction no. 3.: FW: 4.976529e-07 +Flow in reaction no. 4.: FW: 1.784955e-08 +Flow in reaction no. 5.: FW: -4.375475e-06 , RV: 1.890470e-09 +Flow in reaction no. 6.: FW: 1.785916e-04 , RV: 1.298485e-13 +Flow in reaction no. 7.: FW: 1.620350e-04 , RV: 2.277220e-04 +Flow in reaction no. 8.: FW: 3.152837e-03 , RV: 3.105996e-04 +Flow in reaction no. 9.: FW: 6.712880e-08 , RV: 1.796797e-12 Flow in reaction no. 10.: FW: 2.918000e-02 Flow in reaction no. 11.: FW: 7.800000e-02 -Flow in reaction no. 12.: FW: 1.197206e-03 -Flow in reaction no. 13.: FW: 2.095110e-03 +Flow in reaction no. 12.: FW: 1.197865e-03 +Flow in reaction no. 13.: FW: 2.096263e-03 Eigenvector no. 5. Real. -Flow in reaction no. 0.: FW: -1.909804e-07 -Flow in reaction no. 1.: FW: -1.383116e-05 +Flow in reaction no. 0.: FW: -1.901849e-07 +Flow in reaction no. 1.: FW: -1.375398e-05 Flow in reaction no. 2.: FW: 3.323600e-05 -Flow in reaction no. 3.: FW: -1.971435e-07 -Flow in reaction no. 4.: FW: -1.588682e-07 -Flow in reaction no. 5.: FW: -9.987599e-03 , RV: -4.647023e-09 -Flow in reaction no. 6.: FW: -4.697824e-02 , RV: -5.143906e-14 -Flow in reaction no. 7.: FW: -2.896080e-03 , RV: -2.026817e-03 -Flow in reaction no. 8.: FW: -3.202167e-02 , RV: 2.939992e-04 -Flow in reaction no. 9.: FW: -1.199805e-06 , RV: -7.117952e-13 +Flow in reaction no. 3.: FW: -1.969259e-07 +Flow in reaction no. 4.: FW: -1.582185e-07 +Flow in reaction no. 5.: FW: -9.931869e-03 , RV: -4.629689e-09 +Flow in reaction no. 6.: FW: -4.672110e-02 , RV: -5.138227e-14 +Flow in reaction no. 7.: FW: -2.884017e-03 , RV: -2.018528e-03 +Flow in reaction no. 8.: FW: -3.189236e-02 , RV: 2.940647e-04 +Flow in reaction no. 9.: FW: -1.194807e-06 , RV: -7.110093e-13 Flow in reaction no. 10.: FW: 2.918000e-02 Flow in reaction no. 11.: FW: 7.800000e-02 -Flow in reaction no. 12.: FW: -4.745301e-04 -Flow in reaction no. 13.: FW: -8.304277e-04 +Flow in reaction no. 12.: FW: -4.740062e-04 +Flow in reaction no. 13.: FW: -8.295108e-04 diff --git a/test/expected/shn90.des.m2/model.c b/test/expected/shn90.des.m2/model.c index bc70611..c2c0203 100644 --- a/test/expected/shn90.des.m2/model.c +++ b/test/expected/shn90.des.m2/model.c @@ -143,9 +143,9 @@ void calc_jac(double S[equa], double tk, double R[equa], double Jac[equa+1][equa H=1.000000e+00; H2O=5.550000e+01; Ce_ppp=(8.300000e-05-Ce_pppp); -Jac[1][1]=tk*((((((-3.323600e-05-(-((3.200000e+00*HBrO))))+(-1.000000e+00 -*(3.000000e+06*Br_m)))+-5.040000e-01)+(-((8.900000e+03 -*Ce_pppp))))+(-2.000000e+00*(3.000000e+03*(HBrO2*2.000000e+00 +Jac[1][1]=tk*((((((-3.323600e-05-(3.200000e+00*HBrO))+(-1.000000e+00 +*(3.000000e+06*Br_m)))+-5.040000e-01)-(8.900000e+03* +Ce_pppp))+(-2.000000e+00*(3.000000e+03*(HBrO2*2.000000e+00 )))))-(1+4*R[0]); Jac[1][2]=tk*((2.400000e-02+(-1.000000e+00*(3.000000e+06 *HBrO2)))); @@ -177,9 +177,9 @@ Jac[4][1]=tk*((((-((3.200000e+00*HBrO)))+(2.000000e+00*(3.000000e+06 Jac[4][2]=tk*((2.400000e-02+(2.000000e+00*(3.000000e+06 *HBrO2)))); Jac[4][3]=tk*(0.000000e+00); -Jac[4][4]=tk*((((((-3.323600e-05-(-((3.200000e+00*HBrO2))))+( -2.000000e+00*(-((2.000000e-05*(HBrO*2.000000e+00))))) -)+-1.200000e-10)+-8.000000e-02)+-1.400000e-01))-(1+4*R[3]); +Jac[4][4]=tk*((((((-3.323600e-05-(3.200000e+00*HBrO2))+(2.000000e+00 +*(-((2.000000e-05*(HBrO*2.000000e+00))))))+-1.200000e-10 +)+-8.000000e-02)+-1.400000e-01))-(1+4*R[3]); Jac[4][5]=tk*(0.000000e+00); Jac[5][1]=tk*((1.008000e+00+(-1.000000e+00*(-((8.900000e+03 *Ce_pppp)))))); @@ -274,9 +274,9 @@ BrO2=S[4]; H=1.000000e+00; H2O=5.550000e+01; Ce_ppp=(8.300000e-05-Ce_pppp); -Jac[0][0]=(((((-3.323600e-05-(-((3.200000e+00*HBrO))))+(-1.000000e+00 -*(3.000000e+06*Br_m)))+-5.040000e-01)+(-((8.900000e+03 -*Ce_pppp))))+(-2.000000e+00*(3.000000e+03*(HBrO2*2.000000e+00 +Jac[0][0]=(((((-3.323600e-05-(3.200000e+00*HBrO))+(-1.000000e+00 +*(3.000000e+06*Br_m)))+-5.040000e-01)-(8.900000e+03* +Ce_pppp))+(-2.000000e+00*(3.000000e+03*(HBrO2*2.000000e+00 )))); Jac[0][1]=(2.400000e-02+(-1.000000e+00*(3.000000e+06 *HBrO2))); @@ -308,9 +308,9 @@ Jac[3][0]=(((-((3.200000e+00*HBrO)))+(2.000000e+00*(3.000000e+06 Jac[3][1]=(2.400000e-02+(2.000000e+00*(3.000000e+06 *HBrO2))); Jac[3][2]=0.000000e+00; -Jac[3][3]=(((((-3.323600e-05-(-((3.200000e+00*HBrO2))))+( -2.000000e+00*(-((2.000000e-05*(HBrO*2.000000e+00))))) -)+-1.200000e-10)+-8.000000e-02)+-1.400000e-01); +Jac[3][3]=(((((-3.323600e-05-(3.200000e+00*HBrO2))+(2.000000e+00 +*(-((2.000000e-05*(HBrO*2.000000e+00))))))+-1.200000e-10 +)+-8.000000e-02)+-1.400000e-01); Jac[3][4]=0.000000e+00; Jac[4][0]=(1.008000e+00+(-1.000000e+00*(-((8.900000e+03 *Ce_pppp))))); diff --git a/test/expected/shn90.des.m3/model.c b/test/expected/shn90.des.m3/model.c index 3bdcf2e..c86380a 100644 --- a/test/expected/shn90.des.m3/model.c +++ b/test/expected/shn90.des.m3/model.c @@ -58,9 +58,9 @@ Br_m=S_[1]; Ce_pppp=S_[2]; HBrO=S_[3]; BrO2=S_[4]; -jacobi_matx[0][0]=(((((-3.323600e-05-(-((3.200000e+00*HBrO))))+(-1.000000e+00 -*(3.000000e+06*Br_m)))+-5.040000e-01)+(-((8.900000e+03 -*Ce_pppp))))+(-2.000000e+00*(3.000000e+03*(HBrO2*2.000000e+00 +jacobi_matx[0][0]=(((((-3.323600e-05-(3.200000e+00*HBrO))+(-1.000000e+00 +*(3.000000e+06*Br_m)))+-5.040000e-01)-(8.900000e+03* +Ce_pppp))+(-2.000000e+00*(3.000000e+03*(HBrO2*2.000000e+00 )))); jacobi_matx[0][1]=(2.400000e-02+(-1.000000e+00*(3.000000e+06 *HBrO2))); @@ -87,9 +87,9 @@ jacobi_matx[3][0]=(((-((3.200000e+00*HBrO)))+(2.000000e+00*(3.000000e+06 *Br_m)))+(3.000000e+03*(HBrO2*2.000000e+00))); jacobi_matx[3][1]=(2.400000e-02+(2.000000e+00*(3.000000e+06 *HBrO2))); -jacobi_matx[3][3]=(((((-3.323600e-05-(-((3.200000e+00*HBrO2))))+( -2.000000e+00*(-((2.000000e-05*(HBrO*2.000000e+00))))) -)+-1.200000e-10)+-8.000000e-02)+-1.400000e-01); +jacobi_matx[3][3]=(((((-3.323600e-05-(3.200000e+00*HBrO2))+(2.000000e+00 +*(-((2.000000e-05*(HBrO*2.000000e+00))))))+-1.200000e-10 +)+-8.000000e-02)+-1.400000e-01); jacobi_matx[4][0]=(1.008000e+00+(-1.000000e+00*(-((8.900000e+03 *Ce_pppp))))); jacobi_matx[4][2]=(-1.000000e+00*(((8.000000e+04*BrO2)*-1.000000e+00 diff --git a/test/expected/shn90.des.m3/sim.last b/test/expected/shn90.des.m3/sim.last index 2a7652c..901ded3 100644 --- a/test/expected/shn90.des.m3/sim.last +++ b/test/expected/shn90.des.m3/sim.last @@ -1 +1 @@ -1.600000e+04 3.478822e-08 2.049051e-07 3.073803e-07 2.167552e-07 4.995236e-09 +1.600000e+04 3.478823e-08 2.049051e-07 3.073803e-07 2.167552e-07 4.995236e-09 From a5b291f08eb943307eafedd0d269569ff292bbd8 Mon Sep 17 00:00:00 2001 From: Kenneth Geisshirt Date: Sat, 31 Oct 2026 18:58:04 +0100 Subject: [PATCH 07/13] Mode 5: store second and third derivatives by dynamical variables GenerateHessian and GenerateKeldian stored the derivative by each dynamical variable at index i+NoOfSpec()-NumOfConstraint()-1, where i is the row of the matrix, instead of at the next free column. This overwrote the derivative by the last species, left the column of the dynamical variable empty and wrote out of bounds, so kc crashed on models with two parameters and a dynamical variable. EvalJacobian freed its name buffer twice and never freed rename. The new test model hessian covers this case; its second and third derivatives were checked by hand. Co-Authored-By: Claude Opus 5.5 --- src/codegen.c | 14 +- test/expected/hessian.des.m1/stderr | 1 + test/expected/hessian.des.m1/stdout | 48 +++++ test/expected/hessian.des.m2/in.dat | 10 + test/expected/hessian.des.m2/model.c | 96 +++++++++ test/expected/hessian.des.m2/model.h | 14 ++ test/expected/hessian.des.m2/stderr | 4 + test/expected/hessian.des.m2/stdout | 11 + test/expected/hessian.des.m3/model.c | 69 ++++++ test/expected/hessian.des.m3/model.h | 17 ++ test/expected/hessian.des.m3/sim.last | 1 + test/expected/hessian.des.m3/stderr | 0 test/expected/hessian.des.m3/stdout | 11 + test/expected/hessian.des.m4/model.f | 66 ++++++ test/expected/hessian.des.m4/stderr | 0 test/expected/hessian.des.m4/stdout | 11 + test/expected/hessian.des.m5/kcm5const.p | 15 ++ test/expected/hessian.des.m5/kcm5proc.p | 262 +++++++++++++++++++++++ test/expected/hessian.des.m5/stderr | 0 test/expected/hessian.des.m5/stdout | 11 + test/hessian.des | 16 ++ 21 files changed, 670 insertions(+), 7 deletions(-) create mode 100644 test/expected/hessian.des.m1/stderr create mode 100644 test/expected/hessian.des.m1/stdout create mode 100644 test/expected/hessian.des.m2/in.dat create mode 100644 test/expected/hessian.des.m2/model.c create mode 100644 test/expected/hessian.des.m2/model.h create mode 100644 test/expected/hessian.des.m2/stderr create mode 100644 test/expected/hessian.des.m2/stdout create mode 100644 test/expected/hessian.des.m3/model.c create mode 100644 test/expected/hessian.des.m3/model.h create mode 100644 test/expected/hessian.des.m3/sim.last create mode 100644 test/expected/hessian.des.m3/stderr create mode 100644 test/expected/hessian.des.m3/stdout create mode 100644 test/expected/hessian.des.m4/model.f create mode 100644 test/expected/hessian.des.m4/stderr create mode 100644 test/expected/hessian.des.m4/stdout create mode 100644 test/expected/hessian.des.m5/kcm5const.p create mode 100644 test/expected/hessian.des.m5/kcm5proc.p create mode 100644 test/expected/hessian.des.m5/stderr create mode 100644 test/expected/hessian.des.m5/stdout create mode 100644 test/hessian.des diff --git a/src/codegen.c b/src/codegen.c index cacae78..6fd47db 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -375,9 +375,9 @@ void GenerateHessian(void) { } /* for l */ for(l=1; l<=NumOfDynVar(); l++) { GetDynVarNo(l, name); - hess[i][j][i+NoOfSpec()-NumOfConstraint()-1]=TreeCreate(); - TreeDerive(hess[i][j][i+NoOfSpec()-NumOfConstraint()-1], jacobi[i][j], - name); + hess[i][j][dyn]=TreeCreate(); + TreeDerive(hess[i][j][dyn], jacobi[i][j], name); + dyn++; } /* for l */ } /* for j */ StringFree(name); @@ -423,7 +423,7 @@ void EvalJacobian(double *x, double **jac) { } /* if */ } /* for i */ StringFree(name); - StringFree(name); + StringFree(rename); } /* EvalJacobian */ @@ -455,9 +455,9 @@ void GenerateKeldian(void) { } /* for l */ for(l=1; l<=NumOfDynVar(); l++) { GetDynVarNo(l, name); - keld[i][j][k][i+NoOfSpec()-NumOfConstraint()-1]=TreeCreate(); - TreeDerive(keld[i][j][k][i+NoOfSpec()-NumOfConstraint()-1], - hess[i][j][k], name); + keld[i][j][k][dyn]=TreeCreate(); + TreeDerive(keld[i][j][k][dyn], hess[i][j][k], name); + dyn++; } /* for l */ } /* for k */ StringFree(name); diff --git a/test/expected/hessian.des.m1/stderr b/test/expected/hessian.des.m1/stderr new file mode 100644 index 0000000..f259fe2 --- /dev/null +++ b/test/expected/hessian.des.m1/stderr @@ -0,0 +1 @@ +Failure in hqr2 function. Do not trust the given eigenvectors and -values diff --git a/test/expected/hessian.des.m1/stdout b/test/expected/hessian.des.m1/stdout new file mode 100644 index 0000000..4bd6e9a --- /dev/null +++ b/test/expected/hessian.des.m1/stdout @@ -0,0 +1,48 @@ +kc v1.10, (C) Copyright by Kenneth Geisshirt and Keld Nielsen, 1992-1996 +Species used (*=dyn. var.): + *A() + *B() + *z +Parameters declared: + k1 + k2 +Constants declared: + k1 = 1.000000e+00 + k2 = 2.000000e+00 +The Jacobian matrix is: +J(1, 1) = -1.00000000000000e+00 +J(1, 2) = 2.00000000000000e+00 +J(1, 3) = 2.00000000000000e+00 +J(2, 1) = 1.00000000000000e+00 +J(2, 2) = -2.00000000000000e+00 +J(2, 3) = -2.00000000000000e+00 +J(3, 1) = -5.00000000000000e-01 +J(3, 2) = -1.00000000000000e+00 +J(3, 3) = -5.00000000000000e-01 + +The eigenvalues are: + (0.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + (0.0000000000e+00, 0.0000000000e+00) + +The eigenvectors are: + (1.0000000000e+00, 0.0000000000e+00) + (-8.1266414686e-01, 0.0000000000e+00) + (-7.8783712977e-01, 0.0000000000e+00) + + (-2.3900064885e+00, 0.0000000000e+00) + (-2.5424216164e+00, 0.0000000000e+00) + (1.0000000000e+00, 0.0000000000e+00) + + (-4.6560641684e-01, 0.0000000000e+00) + (5.1680328651e-01, 0.0000000000e+00) + (-1.0000000000e+00, 0.0000000000e+00) + +No. 0,REAL part: Left -4.201003e+00, Right 0.000000e+00, Diff. -4.201003e+00 +No. 0,IM part: Left 0.000000e+00, Right 0.000000e+00, Diff 0.000000e+00 +No. 1,REAL part: Left 6.948367e-01, Right 0.000000e+00, Diff. 6.948367e-01 +No. 1,IM part: Left 0.000000e+00, Right 0.000000e+00, Diff 0.000000e+00 +No. 2,REAL part: Left 2.159999e-01, Right 0.000000e+00, Diff. 2.159999e-01 +No. 2,IM part: Left 0.000000e+00, Right 0.000000e+00, Diff 0.000000e+00 + +The eigenvalues diff --git a/test/expected/hessian.des.m2/in.dat b/test/expected/hessian.des.m2/in.dat new file mode 100644 index 0000000..c7bf0d7 --- /dev/null +++ b/test/expected/hessian.des.m2/in.dat @@ -0,0 +1,10 @@ +dt......= 2.000000e+00 +L.......= 1.000000e+02 +prefix..= test +max_t...= 2.000000e+02 +pt1.....= 100 +pt2.....= 100 +period..= 1.000000e+01 +init-val= 1.000000e+00 +init-val= 5.000000e-01 +noise...= 1.000000e-03 diff --git a/test/expected/hessian.des.m2/model.c b/test/expected/hessian.des.m2/model.c new file mode 100644 index 0000000..2856d87 --- /dev/null +++ b/test/expected/hessian.des.m2/model.c @@ -0,0 +1,96 @@ +/* ######################## +*/ + +#include +#include "model.h" +void init_diff_const(void) { +} /* init_diff_const */ + +double reac(double* S, int l) { + double A; + double B; + double z; + A=S[0]; + B=S[1]; + z=S[3]; + switch (l) { + case 0: return (((-1.000000e+00*A)+(((2.000000e+00*z)*z)*B))); +break; + case 1: return ((A+(-1.000000e+00*(((2.000000e+00*z)*z)*B)))); +break; + case 2: return ((((-(z))*A)*B)); +break; + } /* switch */ +} /* reac */ +void eval(double S[equa], double F[equa]) { + double A; + double B; + double z; + if (S[0]<0.0) S[0]=0.0; + A=S[0]; + if (S[1]<0.0) S[1]=0.0; + B=S[1]; + z=S[2]; + F[0] = ((-1.000000e+00*A)+(((2.000000e+00*z)*z)*B)); + F[1] = (A+(-1.000000e+00*(((2.000000e+00*z)*z)*B))); + F[2] = (((-(z))*A)*B); +} /* eval */ +void calc_jac(double S[equa], double tk, double R[equa], double Jac[equa+1][equa+1]) +{ + double A; + double B; + double z; + if (S[0]<0.0) S[0]=0.0; + A=S[0]; + if (S[1]<0.0) S[1]=0.0; + B=S[1]; + z=S[2]; +Jac[1][1]=tk*(-1.000000e+00)-(1+4*R[0]); +Jac[1][2]=tk*(((2.000000e+00*z)*z)); +Jac[1][3]=tk*((((2.000000e+00*z)+(2.000000e+00*z))*B)); +Jac[2][1]=tk*(1.000000e+00); +Jac[2][2]=tk*((-1.000000e+00*((2.000000e+00*z)*z)))-(1+4*R[1]); +Jac[2][3]=tk*((-1.000000e+00*(((2.000000e+00*z)+(2.000000e+00 +*z))*B))); +Jac[3][1]=tk*(((-(z))*B)); +Jac[3][2]=tk*(((-(z))*A)); +Jac[3][3]=tk*(((-1.000000e+00*A)*B))-(1+4*R[2]); +} +double reac_F(double S[equa], double K[equa], double R[equa], double tk, int l) { + double A; + double B; + double z; + A=S[0]; + B=S[1]; + z=S[2]; +switch (l) { +case 1: +return (tk*(((-1.000000e+00*A)+(((2.000000e+00*z)*z)*B)))-S[0]*(1+4*R[0])+K[0]); +break; +case 2: +return (tk*((A+(-1.000000e+00*(((2.000000e+00*z)*z)*B))))-S[1]*(1+4*R[1])+K[1]); +break; +case 3: +return (tk*((((-(z))*A)*B))-S[2]*(1+4*R[2])+K[2]); +break; +} +} +void calc_jac2(double S[equa], double Jac[equa][equa]) +{ +double A; +double B; +double z; +A=S[0]; +B=S[1]; +z=S[2]; +Jac[0][0]=-1.000000e+00; +Jac[0][1]=((2.000000e+00*z)*z); +Jac[0][2]=(((2.000000e+00*z)+(2.000000e+00*z))*B); +Jac[1][0]=1.000000e+00; +Jac[1][1]=(-1.000000e+00*((2.000000e+00*z)*z)); +Jac[1][2]=(-1.000000e+00*(((2.000000e+00*z)+(2.000000e+00 +*z))*B)); +Jac[2][0]=((-(z))*B); +Jac[2][1]=((-(z))*A); +Jac[2][2]=((-1.000000e+00*A)*B); +} diff --git a/test/expected/hessian.des.m2/model.h b/test/expected/hessian.des.m2/model.h new file mode 100644 index 0000000..9c2d8d7 --- /dev/null +++ b/test/expected/hessian.des.m2/model.h @@ -0,0 +1,14 @@ +/* ######################## +*/ + +#define n_grids 0 +#define m_grids 0 +#define equa 3 + +extern void init_diff_const(void); +double D[equa]; +extern double reac(double*, int); +extern void eval(double *, double *); +void calc_jac(double S[equa], double tk, double R[equa], double Jac[equa+1][equa+1]); +extern double reac_F(double S[equa], double K[equa], double R[equa], double tk, int l); +void calc_jac2(double S[equa], double Jac[equa][equa]); diff --git a/test/expected/hessian.des.m2/stderr b/test/expected/hessian.des.m2/stderr new file mode 100644 index 0000000..7edd0c3 --- /dev/null +++ b/test/expected/hessian.des.m2/stderr @@ -0,0 +1,4 @@ +ERROR: The constant ngrid is not defined! +ERROR: The constant mgrid is not defined! +ERROR: Diffusion coeff. for A(0.000000e+00) not found +ERROR: Diffusion coeff. for B(0.000000e+00) not found diff --git a/test/expected/hessian.des.m2/stdout b/test/expected/hessian.des.m2/stdout new file mode 100644 index 0000000..13398dd --- /dev/null +++ b/test/expected/hessian.des.m2/stdout @@ -0,0 +1,11 @@ +kc v1.10, (C) Copyright by Kenneth Geisshirt and Keld Nielsen, 1992-1996 +Species used (*=dyn. var.): + *A() + *B() + *z +Parameters declared: + k1 + k2 +Constants declared: + k1 = 1.000000e+00 + k2 = 2.000000e+00 diff --git a/test/expected/hessian.des.m3/model.c b/test/expected/hessian.des.m3/model.c new file mode 100644 index 0000000..03a9cd6 --- /dev/null +++ b/test/expected/hessian.des.m3/model.c @@ -0,0 +1,69 @@ +/********************************************* + WARNING: This file was generated by kc v1.10 + CopyWrong by Kenneth Geisshirt + ######################## +**********************************************/ +#include "model.h" +#include +#include +void reac(double* S_, double* v_) { +int j_; +double A; +double B; +double z; +A=S_[0]; +B=S_[1]; +z=S_[2]; +v_[0]=(((-1.000000e+00*A)+(((2.000000e+00*z)*z)*B))); +v_[1]=((A+(-1.000000e+00*(((2.000000e+00*z)*z)*B)))); +v_[2]=((((-(z))*A)*B)); +} +void jacobi(double *S_){ +int j_; +double A; +double B; +double z; +A=S_[0]; +B=S_[1]; +z=S_[2]; +jacobi_matx[0][1]=((2.000000e+00*z)*z); +jacobi_matx[0][2]=(((2.000000e+00*z)+(2.000000e+00*z))*B); +jacobi_matx[1][1]=(-1.000000e+00*((2.000000e+00*z)*z)); +jacobi_matx[1][2]=(-1.000000e+00*(((2.000000e+00*z)+(2.000000e+00 +*z))*B)); +jacobi_matx[2][0]=((-(z))*B); +jacobi_matx[2][1]=((-(z))*A); +jacobi_matx[2][2]=((-1.000000e+00*A)*B); +} +void InitValues(void) { +FILE *infile_; +x_[0]=1.000000e+00; +do_print[0]=1; +x_[1]=5.000000e-01; +do_print[1]=1; +x_[2]=1.000000e+00; +do_print[2]=1; +epsmin_=0.000000e+00; +dtime_=2.000000e+00; +prnmode_=0; +etime_=2.000000e+02; +stime_=0.000000e+00; +htime_=1.000000e+00; +epsr_=1.000000e-05; +epsa_=1.000000e-10; +epse_=1.000000e-10; +solver_=1; +step_adjustment_factor=9.000000e-01; +steplimit_increase=1.500000e+00; +steplimit_decrease=5.000000e-01; +htimemin_=1.000000e-20; +begin_print=0.000000e+00; +scaling_=0; +debug_=1; +(void) strcpy(species[0], "A"); +(void) strcpy(species[1], "B"); +(void) strcpy(species[2], "z"); +(void) strcpy(datafilename_,"kinwrkda"); +jacobi_matx[0][0]=-1.000000e+00; +jacobi_matx[1][0]=1.000000e+00; +} diff --git a/test/expected/hessian.des.m3/model.h b/test/expected/hessian.des.m3/model.h new file mode 100644 index 0000000..bb28060 --- /dev/null +++ b/test/expected/hessian.des.m3/model.h @@ -0,0 +1,17 @@ +/********************************************* + WARNING: This file was generated by kc v1.10 + CopyWrong by Kenneth Geisshirt + ######################## +**********************************************/ +#ifndef _MODEL_HEADER_ +#define _MODEL_HEADER_ +#define equa 3 +#undef _DO_PERT_ +#undef PRINT_ON_SCREEN +double x_[equa],x_pert[equa],xscal_[equa]; +int do_print[equa]; +char species[equa][25]; +extern void reac(double *, double *); +extern void jacobi(double *); +extern void InitValues(void); +#endif diff --git a/test/expected/hessian.des.m3/sim.last b/test/expected/hessian.des.m3/sim.last new file mode 100644 index 0000000..0a0b830 --- /dev/null +++ b/test/expected/hessian.des.m3/sim.last @@ -0,0 +1 @@ +2.000000e+02 1.645363e-03 1.498355e+00 2.337396e-02 diff --git a/test/expected/hessian.des.m3/stderr b/test/expected/hessian.des.m3/stderr new file mode 100644 index 0000000..e69de29 diff --git a/test/expected/hessian.des.m3/stdout b/test/expected/hessian.des.m3/stdout new file mode 100644 index 0000000..13398dd --- /dev/null +++ b/test/expected/hessian.des.m3/stdout @@ -0,0 +1,11 @@ +kc v1.10, (C) Copyright by Kenneth Geisshirt and Keld Nielsen, 1992-1996 +Species used (*=dyn. var.): + *A() + *B() + *z +Parameters declared: + k1 + k2 +Constants declared: + k1 = 1.000000e+00 + k2 = 2.000000e+00 diff --git a/test/expected/hessian.des.m4/model.f b/test/expected/hessian.des.m4/model.f new file mode 100644 index 0000000..d97c2a3 --- /dev/null +++ b/test/expected/hessian.des.m4/model.f @@ -0,0 +1,66 @@ +c **************************************************** +c WARNING: This file was generated by kc v1.10 +c CopyWrong 1994 by Kenneth Geisshirt. +c ######################## +c **************************************************** + + subroutine model(ndim,nvar,n,tvar,xvar,fvar,gvar) + +c specification of the user's problem +c right hand sides and jacobi matrix of +c the model equations are evaluated here +c +c tvar : time (explicitly occures only for fodes) +c xvar() : array ndim state space variables +c fvar() : array ndim right hand sides depending on x;alpha,beta,par() +c (in addition f depends explicitly on t for fodes) +c gvar(,): ndim by ndim+2 matrix of first derivatives, +c gvar = [df/dx,df/dalpha,df/dbeta] + +c ------------------------------------------------------- + implicit real*8(a-h,o-z) + dimension xvar(ndim),fvar(ndim),gvar(ndim,nvar) + common/fixp/dummy(40) + common/varp/k1,k2,arg,per +c ------------------------------------------------------- + A = xvar(1) + B = xvar(2) + + z = xvar(3) + + + fvar(1) = (((-1.000000e+00)*A)+((((2.000000e+00)*z)*z)*B)) + fvar(2) = (A+((-1.000000e+00)*((((2.000000e+00)*z)*z)*B))) + fvar(3) = (((-(z))*A)*B) + + gvar(1,1) = (-1.000000e+00) + gvar(1,2) = (((2.000000e+00)*z)*z) + gvar(1,3) = ((((2.000000e+00)*z)+((2.000000e+00)*z))*B) + + gvar(2,1) = (1.000000e+00) + gvar(2,2) = ((-1.000000e+00)*(((2.000000e+00)*z)*z)) + gvar(2,3) = ((-1.000000e+00)*((((2.000000e+00)*z)+((2.000000e+00) + &*z))*B)) + + gvar(3,1) = ((-(z))*B) + gvar(3,2) = ((-(z))*A) + gvar(3,3) = (((-1.000000e+00)*A)*B) + + gvar(1,4) = (0.000000e+00) + gvar(2,4) = (0.000000e+00) + gvar(3,4) = (0.000000e+00) + + + gvar(1,4) = (0.000000e+00) + gvar(2,4) = (0.000000e+00) + gvar(3,4) = (0.000000e+00) + + gvar(1,5) = (0.000000e+00) + gvar(2,5) = (0.000000e+00) + gvar(3,5) = (0.000000e+00) + + + return + end + + diff --git a/test/expected/hessian.des.m4/stderr b/test/expected/hessian.des.m4/stderr new file mode 100644 index 0000000..e69de29 diff --git a/test/expected/hessian.des.m4/stdout b/test/expected/hessian.des.m4/stdout new file mode 100644 index 0000000..13398dd --- /dev/null +++ b/test/expected/hessian.des.m4/stdout @@ -0,0 +1,11 @@ +kc v1.10, (C) Copyright by Kenneth Geisshirt and Keld Nielsen, 1992-1996 +Species used (*=dyn. var.): + *A() + *B() + *z +Parameters declared: + k1 + k2 +Constants declared: + k1 = 1.000000e+00 + k2 = 2.000000e+00 diff --git a/test/expected/hessian.des.m5/kcm5const.p b/test/expected/hessian.des.m5/kcm5const.p new file mode 100644 index 0000000..5d06769 --- /dev/null +++ b/test/expected/hessian.des.m5/kcm5const.p @@ -0,0 +1,15 @@ +(****************************************************** + WARNING: This file was generated by kc v1.10 + CopyWrong 1994 by Kenneth Geisshirt. + ######################## +*******************************************************) +CONST +n=3; +np=3; +VAR +A:LONGREAL; +B:LONGREAL; +z:LONGREAL; +k1:LONGREAL; +k2:LONGREAL; +species : ARRAY[1..n] OF STRING[20]; diff --git a/test/expected/hessian.des.m5/kcm5proc.p b/test/expected/hessian.des.m5/kcm5proc.p new file mode 100644 index 0000000..f9dd319 --- /dev/null +++ b/test/expected/hessian.des.m5/kcm5proc.p @@ -0,0 +1,262 @@ +(****************************************************** + WARNING: This file was generated by kc v1.10 + CopyWrong 1994 by Kenneth Geisshirt. + ######################## +*******************************************************) +PROCEDURE djacobian(xx_:glnarray; VAR dS_:gldjacobian); +BEGIN +A:=xx_[1]; +B:=xx_[2]; +B:=xx_[1]; +dS_[1,1,1]:=0.000000e+00; +dS_[1,1,2]:=0.000000e+00; +dS_[1,1,3]:=0.000000e+00; +dS_[1,2,1]:=0.000000e+00; +dS_[1,2,2]:=0.000000e+00; +dS_[1,2,3]:=(((2)*z)+((2)*z)); +dS_[1,3,1]:=0.000000e+00; +dS_[1,3,2]:=(((2)*z)+((2)*z)); +dS_[1,3,3]:=((4)*B); +dS_[2,1,1]:=0.000000e+00; +dS_[2,1,2]:=0.000000e+00; +dS_[2,1,3]:=0.000000e+00; +dS_[2,2,1]:=0.000000e+00; +dS_[2,2,2]:=0.000000e+00; +dS_[2,2,3]:=((-1)*(((2)*z)+((2)*z))); +dS_[2,3,1]:=0.000000e+00; +dS_[2,3,2]:=((-1)*(((2)*z)+((2)*z))); +dS_[2,3,3]:=((-1)*((4)*B)); +dS_[3,1,1]:=0.000000e+00; +dS_[3,1,2]:=(-(z)); +dS_[3,1,3]:=((-1)*B); +dS_[3,2,1]:=(-(z)); +dS_[3,2,2]:=0.000000e+00; +dS_[3,2,3]:=((-1)*A); +dS_[3,3,1]:=((-1)*B); +dS_[3,3,2]:=((-1)*A); +dS_[3,3,3]:=0.000000e+00; +END; (* djacobian *) + +PROCEDURE ddjacobian(xx_:glnarray;VAR ddS_:glddjacobian); +BEGIN +A:=xx_[1]; +B:=xx_[2]; +z:=xx_[3]; +dds_[1,1,1,1]:=(0); +dds_[1,1,1,2]:=(0); +dds_[1,1,1,3]:=(0); +dds_[1,1,2,1]:=(0); +dds_[1,1,2,2]:=(0); +dds_[1,1,2,3]:=(0); +dds_[1,1,3,1]:=(0); +dds_[1,1,3,2]:=(0); +dds_[1,1,3,3]:=(0); +dds_[1,2,1,1]:=(0); +dds_[1,2,1,2]:=(0); +dds_[1,2,1,3]:=(0); +dds_[1,2,2,1]:=(0); +dds_[1,2,2,2]:=(0); +dds_[1,2,2,3]:=(0); +dds_[1,2,3,1]:=(0); +dds_[1,2,3,2]:=(0); +dds_[1,2,3,3]:=(4); +dds_[1,3,1,1]:=(0); +dds_[1,3,1,2]:=(0); +dds_[1,3,1,3]:=(0); +dds_[1,3,2,1]:=(0); +dds_[1,3,2,2]:=(0); +dds_[1,3,2,3]:=(4); +dds_[1,3,3,1]:=(0); +dds_[1,3,3,2]:=(4); +dds_[1,3,3,3]:=(0); +dds_[2,1,1,1]:=(0); +dds_[2,1,1,2]:=(0); +dds_[2,1,1,3]:=(0); +dds_[2,1,2,1]:=(0); +dds_[2,1,2,2]:=(0); +dds_[2,1,2,3]:=(0); +dds_[2,1,3,1]:=(0); +dds_[2,1,3,2]:=(0); +dds_[2,1,3,3]:=(0); +dds_[2,2,1,1]:=(0); +dds_[2,2,1,2]:=(0); +dds_[2,2,1,3]:=(0); +dds_[2,2,2,1]:=(0); +dds_[2,2,2,2]:=(0); +dds_[2,2,2,3]:=(0); +dds_[2,2,3,1]:=(0); +dds_[2,2,3,2]:=(0); +dds_[2,2,3,3]:=(-4); +dds_[2,3,1,1]:=(0); +dds_[2,3,1,2]:=(0); +dds_[2,3,1,3]:=(0); +dds_[2,3,2,1]:=(0); +dds_[2,3,2,2]:=(0); +dds_[2,3,2,3]:=(-4); +dds_[2,3,3,1]:=(0); +dds_[2,3,3,2]:=(-4); +dds_[2,3,3,3]:=(0); +dds_[3,1,1,1]:=(0); +dds_[3,1,1,2]:=(0); +dds_[3,1,1,3]:=(0); +dds_[3,1,2,1]:=(0); +dds_[3,1,2,2]:=(0); +dds_[3,1,2,3]:=(-1); +dds_[3,1,3,1]:=(0); +dds_[3,1,3,2]:=(-1); +dds_[3,1,3,3]:=(0); +dds_[3,2,1,1]:=(0); +dds_[3,2,1,2]:=(0); +dds_[3,2,1,3]:=(-1); +dds_[3,2,2,1]:=(0); +dds_[3,2,2,2]:=(0); +dds_[3,2,2,3]:=(0); +dds_[3,2,3,1]:=(-1); +dds_[3,2,3,2]:=(0); +dds_[3,2,3,3]:=(0); +dds_[3,3,1,1]:=(0); +dds_[3,3,1,2]:=(-1); +dds_[3,3,1,3]:=(0); +dds_[3,3,2,1]:=(-1); +dds_[3,3,2,2]:=(0); +dds_[3,3,2,3]:=(0); +dds_[3,3,3,1]:=(0); +dds_[3,3,3,2]:=(0); +dds_[3,3,3,3]:=(0); +END; (* ddjacobian *) + +PROCEDURE derivs(bj_:BOOLEAN; xx_:glnarray; t_:LONGREAL; + VAR vv_:glnarray; VAR jj_:glnpbynp); +BEGIN +A:=xx_[1]; +B:=xx_[2]; +z:=xx_[3]; +vv_[1]:=(((-1)*A)+((((2)*z)*z)*B)); +vv_[2]:=(A+((-1)*((((2)*z)*z)*B))); +vv_[3]:=(((-(z))*A)*B); +IF bj_ THEN BEGIN +jj_[1, 2]:=(((2)*z)*z); +jj_[1, 3]:=((((2)*z)+((2)*z))*B); +jj_[2, 2]:=((-1)*(((2)*z)*z)); +jj_[2, 3]:=((-1)*((((2)*z)+((2)*z))*B)); +jj_[3, 1]:=((-(z))*B); +jj_[3, 2]:=((-(z))*A); +jj_[3, 3]:=(((-1)*A)*B); +END; +END; (* derivs *) + +PROCEDURE derivsinit; +BEGIN +species[1]:='A'; +species[2]:='B'; +species[3]:='z'; +epsr:=1.000000e-03; +epsa:=1.000000e-20; +name_datafile:='kinwrkdat'; +xx[1]:=1.000000e+00; +xx[2]:=5.000000e-01; +xx[3]:=1.000000e+00; +jacobi[1, 1]:= -1.000000e+00; +jacobi[2, 1]:= 1.000000e+00; +END; (* derivs *) + +PROCEDURE sp_dalfa(bj_: BOOLEAN;xx_: glnarray; VAR gg_: glnpbynp); +BEGIN +END; (* sp_dalfa *) + +PROCEDURE derpinit; +BEGIN +END; (* derpinit *) + +PROCEDURE hf_dalfa(bj_,tp_: BOOLEAN;xx_: glnarray; VAR gg_: glnpbynp); +BEGIN +A:=xx_[1]; +B:=xx_[2]; +z:=xx_[3]; +IF tp_ THEN BEGIN +k1:=xx_[n1]; +k2:=xx_[n2]; +IF bj_ THEN BEGIN +gg_[1, n1]:=(0); +gg_[2, n1]:=(0); +gg_[3, n1]:=(0); +END; +END +ELSE BEGIN +k2:=xx_[n1]; +k1:=xx_[n2]; +IF bj_ THEN BEGIN +gg_[1, n1]:=(0); +gg_[2, n1]:=(0); +gg_[3, n1]:=(0); +END; +END; +END; (* hf_dalfa *) + +PROCEDURE hopfinit; +BEGIN +need_dd_jac:=TRUE; +maxoutn1:=30; +maxoutn2:=2; +cfout:=10; +ref:=1; +hopfbftp:=-1; +re1:=5.000000e-01; +im1:=5.000000e-01; +maxnoofp:=10; +maxithqr2:=30; +maxitbisec:=30; +maxitintpol:=30; +maxititera:=30; +maxitcorrec:=30; +corrhreg:=10; +hh:=1.000000e+00; +epsfx:=1.000000e-15; +epsblk:=1.000000e-15; +epshqr2:=1.000000e-20; +epsbisecr:=1.000000e-10; +epsmach:=1.000000e-15; +epsdigit:=1.000000e-14; +print_on_screen:=1; +print_on_file:=1; +failure_print:=0; +para_regU:=1; +qc_calc:=0; +hf_calc:=1; +df_calc:=0; +hass_calc:=1; +kura_calc:=0; +eigvec_prn:=0; +name_datafile:= 'kinwrkdat'; +name_textfile:= 'kinwrkdat.t'; +xx[1]:=1.000000e+00; +initndir[1]:=-1; +inithmax[1]:=1.000000e+02; +initxupp[1]:=1.000000e+03; +initxlow[1]:=0.000000e+00; +initpref[1]:=1.000000e-01; +xx[2]:=5.000000e-01; +initndir[2]:=-1; +inithmax[2]:=1.000000e+02; +initxupp[2]:=1.000000e+03; +initxlow[2]:=0.000000e+00; +initpref[2]:=1.000000e-01; +xx[n1]:=1.000000e+00; +initndir[n1]:=1; +inithmax[n1]:=1.000000e-02; +initxlow[n1]:=0.000000e+00; +initxupp[n1]:=1.000000e+01; +initpref[n1]:=1.000000e-04; +xx[n2]:=2.000000e+00; +initndir[n2]:=1; +inithmax[n2]:=1.000000e-02; +initxlow[n2]:=0.000000e+00; +initxupp[n2]:=1.000000e+01; +initpref[n2]:=1.000000e-04; +END; (* hopfinit *) + +PROCEDURE detnumparam; +BEGIN + numparam:=2; +END; (* detnumparam *) + diff --git a/test/expected/hessian.des.m5/stderr b/test/expected/hessian.des.m5/stderr new file mode 100644 index 0000000..e69de29 diff --git a/test/expected/hessian.des.m5/stdout b/test/expected/hessian.des.m5/stdout new file mode 100644 index 0000000..13398dd --- /dev/null +++ b/test/expected/hessian.des.m5/stdout @@ -0,0 +1,11 @@ +kc v1.10, (C) Copyright by Kenneth Geisshirt and Keld Nielsen, 1992-1996 +Species used (*=dyn. var.): + *A() + *B() + *z +Parameters declared: + k1 + k2 +Constants declared: + k1 = 1.000000e+00 + k2 = 2.000000e+00 diff --git a/test/hessian.des b/test/hessian.des new file mode 100644 index 0000000..8ba6f8f --- /dev/null +++ b/test/hessian.des @@ -0,0 +1,16 @@ +/* Second and third derivatives (mode 5) with respect to species and a + dynamical variable. */ +k1 = 1.0; +k2 = 2.0; + +#parameter k1 = 1.0, 0.0, 10.0, 1.0E-2, 0.0001, 1.0; +#parameter k2 = 2.0, 0.0, 10.0, 1.0E-2, 0.0001, 1.0; + +1: A -> B; k> = k1; +2: B -> A; v> = k2*z*z*[B]; + +z' = -z*[A]*[B]; + +[A](0) = 1.0; +[B](0) = 0.5; +z(0) = 1.0; From e5b707237014c5f9fb1d78c2c5b22b666835d5d0 Mon Sep 17 00:00:00 2001 From: Kenneth Geisshirt Date: Sat, 31 Oct 2026 19:18:34 +0100 Subject: [PATCH 08/13] Immutable expression trees in an arena The tree API copied its arguments, mutated the first one in place and left freeing to the caller. TreeCpy never freed what it overwrote and TreeReduce leaked on every call, and the table manager copied trees on both store and lookup without freeing them. Memory was leaked on almost every operation, and kc.y and codegen.c had a use-after-free and a double free. Trees are now immutable and share subtrees: - Every operation returns a new tree: $$=TreeAdd($1, $3) instead of create, add in place, copy and kill. - All nodes come from an arena, released at once by TreeFreeAll() at the end of main. TreeCreate, TreeCpy, TreeKill and TreeAssign* are gone; TreeConst and TreeVar build leaves. - The table manager stores and returns pointers. - Tree is a pointer to const, so the compiler rejects mutation. Reduction runs at the same points as before, so the generated code is unchanged: the outputs of all 79 models in all modes are identical to the previous commit, apart from timestamps. symbmath.c shrinks from about 1560 to 940 lines. InitCodeGenVar allocated the Tree arrays with sizeof(TreeNode) instead of sizeof(Tree). With the correct size, GenerateRateExpr no longer copies a slot past the end of v that was never filled. Co-Authored-By: Claude Opus 5.5 --- src/codegen.c | 224 ++++------ src/conis.c | 12 +- src/kc.y | 99 +---- src/kncont.c | 12 +- src/main.c | 2 + src/mixed.c | 40 +- src/symbmath.c | 1118 ++++++++++++------------------------------------ src/symbmath.h | 44 +- src/tableman.c | 84 ++-- src/tableman.h | 8 +- 10 files changed, 454 insertions(+), 1189 deletions(-) diff --git a/src/codegen.c b/src/codegen.c index 6fd47db..16fc073 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -43,42 +43,42 @@ void InitCodeGenVar(int n, int m, int r) { int i, j, k; - v=(Tree *)calloc(n, sizeof(TreeNode)); - con=(Tree *)calloc(m, sizeof(TreeNode)); - jacobi=(Tree **)calloc(n, sizeof(TreeNode *)); + v=(Tree *)calloc(n, sizeof(Tree)); + con=(Tree *)calloc(m, sizeof(Tree)); + jacobi=(Tree **)calloc(n, sizeof(Tree *)); for(i=0; in) { - rfwds=(Tree **)calloc(r, sizeof(TreeNode *)); + rfwds=(Tree **)calloc(r, sizeof(Tree *)); for(i=0; i0) - GetConstraintNo(constraint, name, &charge, tmp); + tmp=GetConstraintNo(constraint, name, &charge); else - TreeAssignVar(tmp, rename); - TreePow(tmp, temp_tree); - TreeKill(temp_tree); - TreeMul(r[i-1], tmp); - TreeKill(tmp); + tmp=TreeVar(rename); + tmp=TreePow(tmp, TreeConst(temp)); + r[i-1]=TreeMul(r[i-1], tmp); } /* if */ finished=GetNextSpecA(name, &charge, &coeff, 0); } /* while */ } /* if */ else { - GetRateExpr(react_no, uni, 1, r[i-1]); + r[i-1]=GetRateExpr(react_no, uni, 1); for(j=1; j<=NoOfSpec(); j++) { GetSpecNo(j, name, &charge); constraint=IsSpecInConstraint(name, charge); if (constraint>0) { RenameSpec(rename, name, charge); - TreeSubstTree(r[i-1], rename, con[constraint-1]); + r[i-1]=TreeSubstTree(r[i-1], rename, con[constraint-1]); } /* if */ } /* for j */ } /* else */ - TreeCpy(rfw[i-1],r[i-1]); - TreeAssignConst(rrv[i-1],0.0); + rfw[i-1]=r[i-1]; + rrv[i-1]=TreeConst(0.0); break; /* case uni */ case bi: if (GetRateKind(react_no, bi, 1)==1) { - GetRateConst(react_no, bi, 1, r[i-1]); + r[i-1]=GetRateConst(react_no, bi, 1); finished=GetFirstSpecA(react_no, name, &charge, &coeff, 0); while (finished==1) { if (coeff!=0.0) { RenameSpec(rename, name, charge); temp=GetPowConstInReact(react_no, name, charge, 0); - temp_tree=TreeCreate(); - TreeAssignConst(temp_tree, temp); - tmp=TreeCreate(); constraint=IsSpecInConstraint(name, charge); if (constraint>0) - GetConstraintNo(constraint, name, &charge, tmp); + tmp=GetConstraintNo(constraint, name, &charge); else - TreeAssignVar(tmp, rename); - TreePow(tmp, temp_tree); - TreeMul(r[i-1], tmp); - TreeKill(tmp); - TreeKill(temp_tree); + tmp=TreeVar(rename); + tmp=TreePow(tmp, TreeConst(temp)); + r[i-1]=TreeMul(r[i-1], tmp); } /* if */ finished=GetNextSpecA(name, &charge, &coeff, 0); } /* while */ } /* if */ else { - GetRateExpr(react_no, bi, 1, r[i-1]); + r[i-1]=GetRateExpr(react_no, bi, 1); for(j=1; j<=NoOfSpec(); j++) { GetSpecNo(j, name, &charge); constraint=IsSpecInConstraint(name, charge); if (constraint>0) { RenameSpec(rename, name, charge); - TreeSubstTree(r[i-1], rename, con[constraint-1]); + r[i-1]=TreeSubstTree(r[i-1], rename, con[constraint-1]); } /* if */ } /* for j */ } /* else */ - TreeCpy(rfw[i-1],r[i-1]); - v_temp=TreeCreate(); + rfw[i-1]=r[i-1]; if (GetRateKind(react_no, bi, 2)==1) { - GetRateConst(react_no, bi, 2, v_temp); + v_temp=GetRateConst(react_no, bi, 2); finished=GetFirstSpecA(react_no, name, &charge, &coeff, 1); while (finished==1) { if (coeff!=0.0) { RenameSpec(rename, name, charge); temp=GetPowConstInReact(react_no, name, charge, 1); - tmp=TreeCreate(); - temp_tree=TreeCreate(); - TreeAssignConst(temp_tree, temp); constraint=IsSpecInConstraint(name, charge); if (constraint>0) - GetConstraintNo(constraint, name, &charge, tmp); + tmp=GetConstraintNo(constraint, name, &charge); else - TreeAssignVar(tmp, rename); - TreePow(tmp, temp_tree); - TreeMul(v_temp, tmp); - TreeKill(tmp); - TreeKill(temp_tree); + tmp=TreeVar(rename); + tmp=TreePow(tmp, TreeConst(temp)); + v_temp=TreeMul(v_temp, tmp); } /* if */ finished=GetNextSpecA(name, &charge, &coeff, 1); } /* while */ } /* if */ else { - GetRateExpr(react_no, bi, 2, v_temp); + v_temp=GetRateExpr(react_no, bi, 2); for(j=1; j<=NoOfSpec(); j++) { GetSpecNo(j, name, &charge); constraint=IsSpecInConstraint(name, charge); if (constraint>0) { RenameSpec(rename, name, charge); - TreeSubstTree(v_temp, rename, con[constraint-1]); + v_temp=TreeSubstTree(v_temp, rename, con[constraint-1]); } /* if */ } /* for j */ } /* else */ - TreeSub(r[i-1], v_temp); - TreeCpy(rrv[i-1],v_temp); - TreeKill(v_temp); + r[i-1]=TreeSub(r[i-1], v_temp); + rrv[i-1]=v_temp; break; /* case bi */ case equi: fprintf(stderr, "Please use the construction: [J] = expr instead of equilibriums.\n"); @@ -235,37 +214,22 @@ void GenerateRateExpr(void) { for(i=1; i<=NoOfSpec(); i++) { GetSpecNo(i, name, &charge); if (IsSpecInConstraint(name, charge)==0) { - v_store[dyn]=TreeCreate(); + tmp=TreeConst(0.0); for(j=1; j<=NoOfReact(); j++) { - if (j==1) { - tmp=TreeCreate(); - TreeAssignConst(tmp, 0.0); - } /* if */ if (IsSpecInReact(GetReactNo(j-1), name, charge, &coeff)==1) { - v_temp=TreeCreate(); - TreeAssignConst(v_temp, -coeff); - TreeMul(v_temp, r[j-1]); - TreeAdd(tmp, v_temp); - TreeKill(v_temp); - } /* if */ - if (j==NoOfReact()) { - TreeCpy(v_store[dyn], tmp); - TreeKill(tmp); + v_temp=TreeMul(TreeConst(-coeff), r[j-1]); + tmp=TreeAdd(tmp, v_temp); } /* if */ } /* for j */ + v_store[dyn]=tmp; dyn++; } /* if */ } /* for i */ for(i=1; i<=NumOfDynVar(); i++) { - v_store[i+NoOfSpec()-NumOfConstraint()-1]=TreeCreate(); - GetExprNo(i, name, v_store[i+NoOfSpec()-NumOfConstraint()-1]); - } /* for i */ - for(i=0; i<(NoOfSpec()-NumOfConstraint()+NumOfDynVar()+IsNonAutoSystem()); - i++) { - v[i]=TreeCreate(); - TreeCpy(v[i], v_store[i]); - TreeKill(v_store[i]); + v_store[i+NoOfSpec()-NumOfConstraint()-1]=GetExprNo(i, name); } /* for i */ + for(i=0; i<(NoOfSpec()-NumOfConstraint()+NumOfDynVar()); i++) + v[i]=v_store[i]; StringFree(name); StringFree(rename); @@ -276,7 +240,6 @@ void GenerateJacobi(void) { double charge; char *name, *rename, *strtmp; - Tree tmp, temp_tree; int i, j, dyn, dyn2; name=StringAlloc(); @@ -290,37 +253,17 @@ void GenerateJacobi(void) { dyn++; dyn2=1; for(j=1; j<=NoOfSpec(); j++) { - tmp=TreeCreate(); - TreeCpy(tmp, v[dyn-1]); GetSpecNo(j, name, &charge); RenameSpec(rename, name, charge); if (IsSpecInConstraint(name, charge)==0) { - jacobi[dyn-1][dyn2-1]=TreeCreate(); - temp_tree=TreeCreate(); - TreeDerive(temp_tree, tmp, rename); - TreeKill(tmp); - tmp=TreeCreate(); - TreeCpy(tmp, temp_tree); - TreeKill(temp_tree); - (void) TreeEval(tmp); - TreeCpy(jacobi[dyn-1][dyn2-1], tmp); + jacobi[dyn-1][dyn2-1]=TreeDerive(v[dyn-1], rename); + (void) TreeEval(jacobi[dyn-1][dyn2-1]); dyn2++; } /* if */ - TreeKill(tmp); } /* for j */ for(j=1; j<=NumOfDynVar(); j++) { - jacobi[dyn-1][j-1+NoOfSpec()-NumOfConstraint()]=TreeCreate(); - tmp=TreeCreate(); - TreeCpy(tmp, v[dyn-1]); GetDynVarNo(j, name); - temp_tree=TreeCreate(); - TreeDerive(temp_tree, tmp, name); - TreeKill(tmp); - tmp=TreeCreate(); - TreeCpy(tmp, temp_tree); - TreeKill(temp_tree); - TreeCpy(jacobi[dyn-1][j-1+NoOfSpec()-NumOfConstraint()], tmp); - TreeKill(tmp); + jacobi[dyn-1][j-1+NoOfSpec()-NumOfConstraint()]=TreeDerive(v[dyn-1], name); } /* for j */ } /* if */ } /* for i */ @@ -331,15 +274,12 @@ void GenerateJacobi(void) { RenameSpec(rename, name, charge); if (IsSpecInConstraint(name, charge)==0) { dyn++; - jacobi[i+NoOfSpec()-NumOfConstraint()-1][dyn-1]=TreeCreate(); - TreeDerive(jacobi[i+NoOfSpec()-NumOfConstraint()-1][dyn-1], - v[i+NoOfSpec()-NumOfConstraint()-1], rename); + jacobi[i+NoOfSpec()-NumOfConstraint()-1][dyn-1]=TreeDerive(v[i+NoOfSpec()-NumOfConstraint()-1], rename); } /* if */ } /* for j */ for(j=1; j<=NumOfDynVar(); j++) { GetDynVarNo(j, name); - jacobi[i+NoOfSpec()-NumOfConstraint()-1][j+NoOfSpec()-NumOfConstraint()-1]=TreeCreate(); - TreeDerive(jacobi[i+NoOfSpec()-NumOfConstraint()-1][j+NoOfSpec()-NumOfConstraint()-1], v[i+NoOfSpec()-NumOfConstraint()-1], name); + jacobi[i+NoOfSpec()-NumOfConstraint()-1][j+NoOfSpec()-NumOfConstraint()-1]=TreeDerive(v[i+NoOfSpec()-NumOfConstraint()-1], name); } /* for j */ } /* for i */ @@ -368,15 +308,13 @@ void GenerateHessian(void) { GetSpecNo(l, name, &charge); if (IsSpecInConstraint(name, charge)==0) { RenameSpec(rename, name, charge); - hess[i][j][dyn]=TreeCreate(); - TreeDerive(hess[i][j][dyn], jacobi[i][j], rename); + hess[i][j][dyn]=TreeDerive(jacobi[i][j], rename); dyn++; } /* if */ } /* for l */ for(l=1; l<=NumOfDynVar(); l++) { GetDynVarNo(l, name); - hess[i][j][dyn]=TreeCreate(); - TreeDerive(hess[i][j][dyn], jacobi[i][j], name); + hess[i][j][dyn]=TreeDerive(jacobi[i][j], name); dyn++; } /* for l */ } /* for j */ @@ -401,21 +339,19 @@ void EvalJacobian(double *x, double **jac) { for(j=1; j<=NoOfSpec(); j++) { GetSpecNo(j, name, &charge); if (IsSpecInConstraint(name, charge)==0) { - tmp=TreeCreate(); - TreeCpy(tmp, jacobi[dyn-1][dyn2-1]); + tmp=jacobi[dyn-1][dyn2-1]; for(l=1; l<=NoOfSpec(); l++) { GetSpecNo(l, name, &charge); RenameSpec(rename, name, charge); - TreeSubstVar(tmp, rename, x[l-1]); + tmp=TreeSubstVar(tmp, rename, x[l-1]); } /* for l */ for(l=1; l<=NumOfDynVar(); l++) { GetDynVarNo(l, name); - TreeSubstVar(tmp, name, x[l+NoOfSpec()-NumOfConstraint()-1]); + tmp=TreeSubstVar(tmp, name, x[l+NoOfSpec()-NumOfConstraint()-1]); } /* for l */ jac[dyn-1][dyn2-1]=TreeEval(tmp); if (TreeGetError()==NoEval) fprintf(stderr, "WARNING: Was not able to evaluate element (%d, %d) of Jacobian.\n", dyn , dyn2); - TreeKill(tmp); dyn2++; } /* if */ } /* for j */ @@ -448,15 +384,13 @@ void GenerateKeldian(void) { GetSpecNo(l, name, &charge); if (IsSpecInConstraint(name, charge)==0) { RenameSpec(rename, name, charge); - keld[i][j][k][dyn]=TreeCreate(); - TreeDerive(keld[i][j][k][dyn], hess[i][j][k], rename); + keld[i][j][k][dyn]=TreeDerive(hess[i][j][k], rename); dyn++; } /* if */ } /* for l */ for(l=1; l<=NumOfDynVar(); l++) { GetDynVarNo(l, name); - keld[i][j][k][dyn]=TreeCreate(); - TreeDerive(keld[i][j][k][dyn], hess[i][j][k], name); + keld[i][j][k][dyn]=TreeDerive(hess[i][j][k], name); dyn++; } /* for l */ } /* for k */ @@ -481,10 +415,8 @@ void GenerateDiffReac(void) { GetSpecNo(j, name, &charge); if (IsSpecInConstraint(name, charge)==0) { RenameSpec(rename, name, charge); - rfwds[i-1][dyn]=TreeCreate(); - TreeDerive(rfwds[i-1][dyn], rfw[i-1], rename); - rrvds[i-1][dyn]=TreeCreate(); - TreeDerive(rrvds[i-1][dyn], rrv[i-1], rename); + rfwds[i-1][dyn]=TreeDerive(rfw[i-1], rename); + rrvds[i-1][dyn]=TreeDerive(rrv[i-1], rename); dyn++; } /* if */ } /* for j */ @@ -492,10 +424,8 @@ void GenerateDiffReac(void) { /* NumInd=j+NoOfSpec()-NumOfConstraint(); GetDynVarNo(j, name); - rfwds[i][NumInd]=TreeCreate(); - TreeDerive(rfwds[i][NumInd], rfw[i], name); - rrvds[i][NumInd]=TreeCreate(); - TreeDerive(rrvds[i][NumInd], rrv[i], name); + rfwds[i][NumInd]=TreeDerive(rfw[i], name); + rrvds[i][NumInd]=TreeDerive(rrv[i], name); */ } /* for j */ } /* for i */ diff --git a/src/conis.c b/src/conis.c index 37013ea..33542fd 100644 --- a/src/conis.c +++ b/src/conis.c @@ -149,12 +149,10 @@ void ConIS(FILE *fcode) { else RenameSpec(rename, name, charge); for(j=0; j=1; i--) { @@ -585,12 +581,10 @@ void KnCont(FILE *pcode, FILE *hcode) { else strcpy(rename, name); for(j=0; j #include "codecall.h" #include "misc.h" +#include "symbmath.h" int mode; @@ -69,4 +70,5 @@ int main(int argc, char *argv[]) { } /* switch */ (void) yyparse(); CodeGenCall(mode); + TreeFreeAll(); } diff --git a/src/mixed.c b/src/mixed.c index c190a23..660324c 100644 --- a/src/mixed.c +++ b/src/mixed.c @@ -99,117 +99,107 @@ void Mixed(void) { for(i=0; i #include #include +#include #include "symbmath.h" #include "misc.h" -#include +static int tree_error, len; -int tree_error, len, left, right; +/**************************************************************************** + Node arena. Nodes are never freed one by one: trees share subtrees, and + kc builds them for a single run. TreeFreeAll releases all of them. +*****************************************************************************/ -#undef WORKING +#define BlockSize 4096 -/**************************************************************************** - TreeReduce tries to reduce the complexity of the expression. The routine - is an internal one only, i.e. it is not called by the user explicitely. +typedef struct Block { + struct Block *next; + int used; + TreeNode nodes[BlockSize]; +} Block; + +static Block *blocks=NULL; + +static TreeNode *NewNode(TreeTag tag) { + + TreeNode *t; - The code is _not_ commented, but at many reductions one can find a short - explaination. The notation is: Expression 1 -> Expression 2. It should be - read as: Expression 1 is reduced to expression 2. The symbols f and g - represents two generic expressions. + if ((blocks==NULL) || (blocks->used==BlockSize)) { + Block *b=malloc(sizeof(Block)); + if (b==NULL) { + fprintf(stderr, "ERROR: Out of memory.\nAborting kc - sorry.\n"); + exit(-1); + } + b->next=blocks; + b->used=0; + blocks=b; + } + t=&blocks->nodes[blocks->used++]; + memset(t, 0, sizeof(*t)); + t->tag=tag; + return t; +} /* NewNode */ + +void TreeFreeAll(void) { + + while (blocks!=NULL) { + Block *next=blocks->next; + free(blocks); + blocks=next; + } +} /* TreeFreeAll */ + +/**************************************************************************** + Unreduced node builders. *****************************************************************************/ -void TreeReduce(Tree tin) { - - Tree res, t; - int alter; - - alter=0; - res=TreeCreate(); - t=TreeCreate(); - if (tin!=NULL) { - switch (tin->tag) { - case Oper: - alter=2; - TreeCpy(t, tin); - TreeReduce(t->data.oper.left); - TreeReduce(t->data.oper.right); - switch (t->data.oper.op) { - case Add: - if ((t->data.oper.left->tag==Konst) && - (t->data.oper.right->tag==Konst)) { - alter=1; - res->tag=Konst; - res->data.value=t->data.oper.left->data.value - +t->data.oper.right->data.value; - } /* if */ - if ((t->data.oper.right->tag==Konst) && (alter==2)) { - if (t->data.oper.right->data.value==0.0) { - alter=1; - TreeCpy(res, t->data.oper.left); - } /* if */ - } /* if */ - if ((t->data.oper.left->tag==Konst) && (alter==2)) { - if (t->data.oper.left->data.value==0.0) { - alter=1; - TreeCpy(res, t->data.oper.right); - } /* if */ - } /* if */ +static Tree Op(TreeOper op, Tree left, Tree right) { - /* (f+(-g)) -> (f-g) */ - if ((t->data.oper.right->tag==NegSign) && (alter==2)) { - alter=1; - res->tag=Oper; - res->data.oper.op=Sub; - res->data.oper.left=TreeCreate(); - TreeCpy(res->data.oper.left, t->data.oper.left); - res->data.oper.right=TreeCreate(); - TreeCpy(res->data.oper.right, t->data.oper.right->data.right); - } /* if */ - break; - case Sub: - if ((t->data.oper.left->tag==Konst) && - (t->data.oper.right->tag==Konst)) { - alter=1; - res->tag=Konst; - res->data.value=t->data.oper.left->data.value - -t->data.oper.right->data.value; - } /* if */ - if ((t->data.oper.right->tag==Konst) && (alter==2)) - if (t->data.oper.right->data.value==0.0) { - alter=1; - TreeCpy(res, t->data.oper.left); - } /* if */ - - if ((t->data.oper.left->tag==Konst) && (alter==2)) { - if (t->data.oper.left->data.value==0.0) { - alter=1; - res->tag=NegSign; - res->data.right=TreeCreate(); - TreeCpy(res->data.right, t->data.oper.right); - } - } /* if */ - if ((t->data.oper.left->tag==Var) && - (t->data.oper.right->tag==Var)) - if (strcmp(t->data.oper.left->data.name, - t->data.oper.right->data.name)==0) { - alter=1; - res->tag=Konst; - res->data.value=0.0; - } /* if */ - - /* (f-(-g)) -> (f+g) */ - if ((t->data.oper.right->tag==NegSign) && (alter==2)) { - alter=1; - res->tag=Oper; - res->data.oper.op=Add; - res->data.oper.left=TreeCreate(); - TreeCpy(res->data.oper.left, t->data.oper.left); - res->data.oper.right=TreeCreate(); - TreeCpy(res->data.oper.right, t->data.oper.right->data.right); - } /* if */ - - /* (-f-g) -> -(f+g) */ - if ((t->data.oper.left->tag==NegSign) && (alter==2)) { - alter=1; - res->tag=NegSign; - res->data.right=TreeCreate(); - res->data.right->tag=Oper; - res->data.right->data.oper.op=Add; - res->data.right->data.oper.left=TreeCreate(); - TreeCpy(res->data.right->data.oper.left, - t->data.oper.left->data.right); - res->data.right->data.oper.right=TreeCreate(); - TreeCpy(res->data.right->data.oper.right, t->data.oper.right); - } - break; + TreeNode *t=NewNode(Oper); - case Mul: + t->data.oper.op=op; + t->data.oper.left=left; + t->data.oper.right=right; + return t; +} /* Op */ - /* (Konst1*Konst2) -> Konst3 */ - if ((t->data.oper.left->tag==Konst) && - (t->data.oper.right->tag==Konst)) { - alter=1; - res->tag=Konst; - res->data.value=t->data.oper.left->data.value - *t->data.oper.right->data.value; - } /* if */ +static Tree Const(double value) { - /* (f*0) -> 0 and (f*1) -> (f) */ - if ((t->data.oper.right->tag==Konst) && (alter==2)) { - if (t->data.oper.right->data.value==0.0) { - alter=1; - res->tag=Konst; - res->data.value=0.0; - }; /* if */ - if (t->data.oper.right->data.value==1.0) { - alter=1; - TreeCpy(res, t->data.oper.left); - } /* if */ - } /* if */ + TreeNode *t=NewNode(Konst); - /* (0*f) -> 0 and (1*f) -> (f) */ - if ((t->data.oper.left->tag==Konst) && (alter==2)) { - if (t->data.oper.left->data.value==0.0) { - alter=1; - res->tag=Konst; - res->data.value=0.0; - } /* if */ - if (t->data.oper.left->data.value==1.0) { - alter=1; - TreeCpy(res, t->data.oper.right); - } /* if */ - } /* if */ + t->data.value=value; + return t; +} /* Const */ -#ifdef WORKING - /* (-1*f) -> (-f) */ - if ((t->data.oper.left->tag==Konst) && (alter==2)) - if (t->data.oper.left->data.value==-1.0) { - alter=1; - res->tag=NegSign; - res->data.right=TreeCreate(); - TreeCpy(res->data.right, t->data.oper.right); - } /* if */ - - /* (f*(-1)) -> (-f) */ - if ((t->data.oper.right->tag==Konst) && (alter==2)) - if (t->data.oper.right->data.value==-1.0) { - alter=1; - res->tag=NegSign; - res->data.right=TreeCreate(); - TreeCpy(res->data.right, t->data.oper.left); - } /* if */ -#endif +static Tree Fun(Function fun, Tree arg) { - break; - case Div: - if ((t->data.oper.left->tag==Konst) && - (t->data.oper.right->tag==Konst)) { - /* division by zero is not detected */ - alter=1; - res->tag=Konst; - res->data.value=t->data.oper.left->data.value - /t->data.oper.right->data.value; - } /* if */ - if ((t->data.oper.right->tag==Konst) && (alter==2)) { - if (t->data.oper.right->data.value==1.0) { - alter=1; - TreeCpy(res, t->data.oper.left); - } /* if */ - if (t->data.oper.right->data.value==0.0) { - alter=1; - res->tag=Konst; - res->data.value=0.0; - } /* if */ - } /* if */ - if ((t->data.oper.left->tag==Var) && (t->data.oper.right->tag==Var)) { - if (strcmp(t->data.oper.left->data.name, - t->data.oper.right->data.name)==0) { - alter=1; - res->tag=Konst; - res->data.value=1.0; - } /* if */ - } /* if */ - if ((t->data.oper.left->tag==Konst) && (alter==2)) - if (t->data.oper.left->data.value==0.0) { - alter=1; - res->tag=Konst; - res->data.value=0.0; - } /* if */ - break; - case Pow: - if ((t->data.oper.left->tag==Konst) && - (t->data.oper.right->tag==Konst)) { - alter=1; - res->tag=Konst; - res->data.value=pow(t->data.oper.left->data.value, - t->data.oper.right->data.value); - } /* if */ - if ((t->data.oper.right->tag==Konst) && (alter==2)) { - if (t->data.oper.right->data.value==1.0) { - alter=1; - TreeCpy(res, t->data.oper.left); - } /* if */ - if (t->data.oper.right->data.value==0.0) { - alter=1; - res->tag=Konst; - res->data.value=1.0; - } /* if */ - } /* if */ - break; - } /* switch */ - break; - case NegSign: - alter=2; - t=TreeCreate(); - TreeCpy(t, tin); - TreeReduce(t->data.right); - - /* (-(-f)) -> (f) */ - if (t->data.right->tag==NegSign) { - alter=1; - res->tag=t->data.right->data.right->tag; - res->data.right=TreeCreate(); - TreeCpy(res, t->data.right->data.right); - } /* if */ + TreeNode *t=NewNode(Func); - /* -(Constant) -> (-Constant) */ - if (t->data.right->tag==Konst) { - alter=1; - res->tag=Konst; - res->data.value=-t->data.right->data.value; - } /* if */ - break; - case Func: - alter=2; - t=TreeCreate(); - TreeCpy(t, tin); - TreeReduce(t->data.func.right); - break; - default: - /* Nothing */ - alter=0; - break; - }; /* switch tag */ - switch (alter) { - case 0: /* nothing altered */ - TreeCpy(res, tin); - break; - case 1: /* res is the result */ - break; - case 2: /* t is the result */ - TreeCpy(res, t); - break; - }; /* switch */ -/* - TreeKill(tin); - tin=TreeCreate(); -*/ - TreeCpy(tin, res); - TreeKill(res); - TreeKill(t); - } /* if */ - else { - fprintf(stderr, "ERROR in TreeReduce: NULL pointer.\nAborting kc - sorry.\n"); - exit(-1); - } -} /* TreeReduce */ + t->data.func.fun=fun; + t->data.func.right=arg; + return t; +} /* Fun */ + +static Tree Neg(Tree arg) { + + TreeNode *t=NewNode(NegSign); + + t->data.right=arg; + return t; +} /* Neg */ + +static int IsConst(Tree t, double value) { + return (t->tag==Konst) && (t->data.value==value); +} /* IsConst */ + +static int SameVar(Tree a, Tree b) { + + return (a->tag==Var) && (b->tag==Var) + && (strcmp(a->data.name, b->data.name)==0); +} /* SameVar */ /**************************************************************************** - The following two procdures are used by TreePrint. + Reduce returns a simpler tree with the same value. It reduces the + subtrees, then applies the first matching rule below to the node. The + notation f, g stands for any expression, K for a constant. *****************************************************************************/ -void SplitFP(double x, double *mantissa, int *exponent) { - - int i, sign; - char str[STRING_LENGTH]; - - *mantissa=0.0; - sprintf(str, "%e", x); - if (str[0]=='-') - sign=-1; - else - sign=1; - i=1; - while (str[i]!='e') { - *mantissa=*mantissa+(double)str[i]*pow(10.0, -(double)(i-1)); - i++; - } /* while */ - *mantissa=*mantissa*sign; - i+=2; - if (str[i]=='-') - sign=-1; - else - sign=1; - *exponent=10*(int)str[i+1]; - *exponent+=(int)str[i+2]; - *exponent*=sign; -} /* SplitFP */ - - -void LineBreak(FILE *out, int mode) { +static Tree Reduce(Tree t) { + + Tree l, r; + + if (t==NULL) { + fprintf(stderr, "ERROR in TreeReduce: NULL pointer.\nAborting kc - sorry.\n"); + exit(-1); + } + switch (t->tag) { + case Oper: + l=Reduce(t->data.oper.left); + r=Reduce(t->data.oper.right); + switch (t->data.oper.op) { + case Add: + if ((l->tag==Konst) && (r->tag==Konst)) /* K1+K2 -> K3 */ + return Const(l->data.value+r->data.value); + if (IsConst(r, 0.0)) return l; /* f+0 -> f */ + if (IsConst(l, 0.0)) return r; /* 0+f -> f */ + if (r->tag==NegSign) /* f+(-g) -> f-g */ + return Op(Sub, l, r->data.right); + break; + case Sub: + if ((l->tag==Konst) && (r->tag==Konst)) /* K1-K2 -> K3 */ + return Const(l->data.value-r->data.value); + if (IsConst(r, 0.0)) return l; /* f-0 -> f */ + if (IsConst(l, 0.0)) return Neg(r); /* 0-f -> -f */ + if (SameVar(l, r)) return Const(0.0); /* x-x -> 0 */ + if (r->tag==NegSign) /* f-(-g) -> f+g */ + return Op(Add, l, r->data.right); + if (l->tag==NegSign) /* (-f)-g -> -(f+g) */ + return Neg(Op(Add, l->data.right, r)); + break; + case Mul: + if ((l->tag==Konst) && (r->tag==Konst)) /* K1*K2 -> K3 */ + return Const(l->data.value*r->data.value); + if (IsConst(r, 0.0)) return Const(0.0); /* f*0 -> 0 */ + if (IsConst(r, 1.0)) return l; /* f*1 -> f */ + if (IsConst(l, 0.0)) return Const(0.0); /* 0*f -> 0 */ + if (IsConst(l, 1.0)) return r; /* 1*f -> f */ + break; + case Div: + if ((l->tag==Konst) && (r->tag==Konst)) /* K1/K2 -> K3 */ + return Const(l->data.value/r->data.value); + if (IsConst(r, 1.0)) return l; /* f/1 -> f */ + if (IsConst(r, 0.0)) return Const(0.0); /* f/0 -> 0 (sic) */ + if (SameVar(l, r)) return Const(1.0); /* x/x -> 1 */ + if (IsConst(l, 0.0)) return Const(0.0); /* 0/f -> 0 */ + break; + case Pow: + if ((l->tag==Konst) && (r->tag==Konst)) /* K1^K2 -> K3 */ + return Const(pow(l->data.value, r->data.value)); + if (IsConst(r, 1.0)) return l; /* f^1 -> f */ + if (IsConst(r, 0.0)) return Const(1.0); /* f^0 -> 1 */ + break; + } + return Op(t->data.oper.op, l, r); + case NegSign: + r=Reduce(t->data.right); + if (r->tag==NegSign) return r->data.right; /* -(-f) -> f */ + if (r->tag==Konst) return Const(-r->data.value); /* -(K) -> (-K) */ + return Neg(r); + case Func: + return Fun(t->data.func.fun, Reduce(t->data.func.right)); + default: + return t; + } +} /* Reduce */ + + +static void LineBreak(FILE *out, int mode) { if ((len>=60)) { fprintf(out, "\n"); @@ -370,484 +215,154 @@ void LineBreak(FILE *out, int mode) { The following routines are exported. *************************************************************************** */ - int TreeGetError(void) { return tree_error; } /* TreeGetError */ +Tree TreeConst(double value) { -Tree TreeCreate(void) { - - Tree t; - - t=(Tree) calloc(1, sizeof(TreeNode)); - if (t==NULL) { - fprintf(stderr, "ERROR in TreeCreate: NULL pointer recieved.\nAborting kc - sorry.\n"); - exit(-1); - } tree_error=0; - return t; -} /* TreeCreate */ + return Const(value); +} /* TreeConst */ +Tree TreeVar(const char *name) { -void TreeAdd(Tree t1, Tree t2) { - - Tree t; - - t=TreeCreate(); - t->tag=Oper; - t->data.oper.op=Add; - t->data.oper.left=TreeCreate(); - t->data.oper.right=TreeCreate(); - TreeCpy(t->data.oper.left, t1); - TreeCpy(t->data.oper.right, t2); - tree_error=0; - TreeReduce(t); - TreeCpy(t1, t); - TreeKill(t); -} /* TreeAdd */ - -void TreeSub(Tree t1, Tree t2) { - - Tree t; - - t=TreeCreate(); - t->tag=Oper; - t->data.oper.op=Sub; - t->data.oper.left=TreeCreate(); - t->data.oper.right=TreeCreate(); - TreeCpy(t->data.oper.left, t1); - TreeCpy(t->data.oper.right, t2); - tree_error=0; - TreeReduce(t); - TreeCpy(t1, t); - TreeKill(t); -} /* TreeSub */ - -void TreeMul(Tree t1, Tree t2) { - - Tree t; - - t=TreeCreate(); - t->tag=Oper; - t->data.oper.op=Mul; - t->data.oper.left=TreeCreate(); - t->data.oper.right=TreeCreate(); - TreeCpy(t->data.oper.left, t1); - TreeCpy(t->data.oper.right, t2); - tree_error=0; - TreeReduce(t); - TreeCpy(t1, t); - TreeKill(t); -} /* TreeMul */ + TreeNode *t=NewNode(Var); -void TreeDiv(Tree t1, Tree t2) { - - Tree t; - - t=TreeCreate(); - t->tag=Oper; - t->data.oper.op=Div; - t->data.oper.left=TreeCreate(); - t->data.oper.right=TreeCreate(); - TreeCpy(t->data.oper.left, t1); - TreeCpy(t->data.oper.right, t2); - tree_error=0; - TreeReduce(t); - TreeCpy(t1, t); - TreeKill(t); -} /* TreeDiv */ - -void TreePow(Tree t, Tree t2) { - - Tree res; - - res=TreeCreate(); - res->tag=Oper; - res->data.oper.op=Pow; - res->data.oper.left=TreeCreate(); - res->data.oper.right=TreeCreate(); - TreeCpy(res->data.oper.left, t); - TreeCpy(res->data.oper.right, t2); - TreeReduce(res); - tree_error=0; - TreeCpy(t, res); - TreeKill(res); -} /* TreePow */ - -void TreeSign(Tree t) { - - Tree res; - - res=TreeCreate(); - res->tag=NegSign; - res->data.right=TreeCreate(); - TreeCpy(res->data.right, t); - TreeReduce(res); -/* TreeKill(t); - t=TreeCreate(); */ - TreeCpy(t, res); - TreeKill(res); - tree_error=0; -} /* TreeSign */ - -void TreeAssignConst(Tree t, double val) { - - t->tag=Konst; - t->data.value=val; - tree_error=0; -} /* TreeAssignConst */ - - -void TreeAssignVar(Tree t, char *name) { - - t->tag=Var; (void) strcpy(t->data.name, name); tree_error=0; -} /* TreeAssignVar */ - - -void TreeSubstVar(Tree t, char* name, double val) { - - if (t==NULL) - tree_error=1; - else { - switch (t->tag) { - case Var: - if (strcmp(t->data.name, name)==0) { - t->tag=Konst; - t->data.value=val; - tree_error=0; - } /* if */ - break; - case Oper: - TreeSubstVar(t->data.oper.left, name, val); - TreeSubstVar(t->data.oper.right, name, val); - break; - case NegSign: - TreeSubstVar(t->data.right, name, val); - break; - case Func: - TreeSubstVar(t->data.func.right, name, val); - break; - default: - break; - } /* switch tag */ - tree_error=0; - } /* else */ - TreeReduce(t); -} /* TreeSubstVar */ - -void TreeSubstTree(Tree t, char *name, Tree value) { - - if (t==NULL) - tree_error=1; - else { - switch (t->tag) { - case Var: - if (strcmp(t->data.name, name)==0) - TreeCpy(t, value); - break; - case Oper: - TreeSubstTree(t->data.oper.left, name, value); - TreeSubstTree(t->data.oper.right, name, value); - break; - case Func: - TreeSubstTree(t->data.func.right, name, value); - break; - case NegSign: - TreeSubstTree(t->data.right, name, value); - break; - default: - break; - } /* switch */ - tree_error=0; - TreeReduce(t); - } /* else */ -} /* TreeSubstTree */ - -/* Builders for TreeDerive: unreduced nodes, the result is reduced once. */ -static Tree Op(TreeOper op, Tree left, Tree right) { - - Tree t=TreeCreate(); - - t->tag=Oper; - t->data.oper.op=op; - t->data.oper.left=left; - t->data.oper.right=right; - return t; -} /* Op */ - -static Tree Const(double value) { - - Tree t=TreeCreate(); - - t->tag=Konst; - t->data.value=value; return t; -} /* Const */ - -static Tree Fun(Function fun, Tree arg) { +} /* TreeVar */ - Tree t=TreeCreate(); +static Tree Reduced(Tree t) { - t->tag=Func; - t->data.func.fun=fun; - t->data.func.right=arg; + t=Reduce(t); + tree_error=0; return t; -} /* Fun */ +} /* Reduced */ -static Tree Neg(Tree arg) { +Tree TreeAdd(Tree a, Tree b) { return Reduced(Op(Add, a, b)); } +Tree TreeSub(Tree a, Tree b) { return Reduced(Op(Sub, a, b)); } +Tree TreeMul(Tree a, Tree b) { return Reduced(Op(Mul, a, b)); } +Tree TreeDiv(Tree a, Tree b) { return Reduced(Op(Div, a, b)); } +Tree TreePow(Tree a, Tree b) { return Reduced(Op(Pow, a, b)); } +Tree TreeSign(Tree a) { return Reduced(Neg(a)); } +Tree TreeApplyFunc(Function fun, Tree a) { return Reduced(Fun(fun, a)); } - Tree t=TreeCreate(); +/* Replaces the variable name by value. Like the original implementation, + it reduces at every level of the tree. */ +Tree TreeSubstTree(Tree t, const char *name, Tree value) { - t->tag=NegSign; - t->data.right=arg; - return t; -} /* Neg */ + Tree res; -static Tree Copy(Tree t) { + if (t==NULL) { + tree_error=1; + return NULL; + } + switch (t->tag) { + case Var: + res=(strcmp(t->data.name, name)==0) ? value : t; + break; + case Oper: + res=Op(t->data.oper.op, TreeSubstTree(t->data.oper.left, name, value), + TreeSubstTree(t->data.oper.right, name, value)); + break; + case Func: + res=Fun(t->data.func.fun, TreeSubstTree(t->data.func.right, name, value)); + break; + case NegSign: + res=Neg(TreeSubstTree(t->data.right, name, value)); + break; + default: + res=t; + break; + } + return Reduced(res); +} /* TreeSubstTree */ - Tree c=TreeCreate(); +Tree TreeSubstVar(Tree t, const char *name, double value) { - TreeCpy(c, t); - return c; -} /* Copy */ + return TreeSubstTree(t, name, Const(value)); +} /* TreeSubstVar */ -void TreeDerive(Tree res, Tree t, char* name) { +/* Derivative of t with respect to name. Every level is reduced once. */ +Tree TreeDerive(Tree t, const char *name) { - Tree t1, t2, t3, u; + Tree res=NULL, f, g, u, du; tree_error=0; - if (t!=NULL) { - switch (t->tag) { - case Konst: - res->tag=Konst; - res->data.value=0.0; - break; - case Var: - res->tag=Konst; - if (strcmp(t->data.name, name)==0) - res->data.value=1.0; - else - res->data.value=0.0; - break; - case Oper: - switch (t->data.oper.op) { - case Add: - res->tag=Oper; - res->data.oper.op=Add; - res->data.oper.left=TreeCreate(); - res->data.oper.right=TreeCreate(); - TreeDerive(res->data.oper.left, t->data.oper.left, name); - TreeDerive(res->data.oper.right, t->data.oper.right, name); - break; - case Sub: - res->tag=Oper; - res->data.oper.op=Sub; - res->data.oper.left=TreeCreate(); - res->data.oper.right=TreeCreate(); - TreeDerive(res->data.oper.left, t->data.oper.left, name); - TreeDerive(res->data.oper.right, t->data.oper.right, name); - break; - case Mul: - res->data.oper.left=TreeCreate(); - res->data.oper.right=TreeCreate(); - res->tag=Oper; - res->data.oper.op=Add; - res->data.oper.left->tag=Oper; - res->data.oper.left->data.oper.op=Mul; - res->data.oper.right->tag=Oper; - res->data.oper.right->data.oper.op=Mul; - res->data.oper.right->data.oper.left=TreeCreate(); - res->data.oper.right->data.oper.right=TreeCreate(); - res->data.oper.left->data.oper.left=TreeCreate(); - res->data.oper.left->data.oper.right=TreeCreate(); - TreeDerive(res->data.oper.left->data.oper.left, - t->data.oper.left, name); - TreeCpy(res->data.oper.left->data.oper.right, t->data.oper.right); - TreeCpy(res->data.oper.right->data.oper.left, t->data.oper.left); - TreeDerive(res->data.oper.right->data.oper.right, - t->data.oper.right, name); - break; - case Div: - res->tag=Oper; - res->data.oper.op=Div; - res->data.oper.left=TreeCreate(); - res->data.oper.right=TreeCreate(); - res->data.oper.right->tag=Oper; - res->data.oper.right->data.oper.op=Pow; - res->data.oper.right->data.oper.left=TreeCreate(); - res->data.oper.right->data.oper.right=TreeCreate(); - res->data.oper.right->data.oper.right->tag=Konst; - res->data.oper.right->data.oper.right->data.value=2.0; - TreeCpy(res->data.oper.right->data.oper.left, t->data.oper.right); - res->data.oper.left->tag=Oper; - res->data.oper.left->data.oper.op=Sub; - res->data.oper.left->data.oper.left=TreeCreate(); - res->data.oper.left->data.oper.right=TreeCreate(); - res->data.oper.left->data.oper.left->tag=Oper; - res->data.oper.left->data.oper.left->data.oper.op=Mul; - res->data.oper.left->data.oper.left->data.oper.left=TreeCreate(); - res->data.oper.left->data.oper.left->data.oper.right=TreeCreate(); - TreeCpy(res->data.oper.left->data.oper.left->data.oper.left, - t->data.oper.right); - TreeDerive(res->data.oper.left->data.oper.left->data.oper.right, - t->data.oper.left, name); - res->data.oper.left->data.oper.right->tag=Oper; - res->data.oper.left->data.oper.right->data.oper.op=Mul; - res->data.oper.left->data.oper.right->data.oper.left=TreeCreate(); - res->data.oper.left->data.oper.right->data.oper.right=TreeCreate(); - TreeCpy(res->data.oper.left->data.oper.right->data.oper.left, - t->data.oper.left); - TreeDerive(res->data.oper.left->data.oper.right->data.oper.right, - t->data.oper.right, name); - break; - case Pow: /* (f^g)' = g*f^(g-1)*f' + f^g*log(f)*g' */ - t1=TreeCreate(); - t2=TreeCreate(); - TreeAssignConst(t1, 1.0); - TreeCpy(t2, t->data.oper.right); - TreeSub(t2, t1); - TreeKill(t1); - t1=TreeCreate(); - TreeCpy(t1, t->data.oper.left); - TreePow(t1, t2); - TreeKill(t2); - t2=TreeCreate(); - TreeDerive(t2, t->data.oper.left, name); - TreeMul(t1, t2); - TreeMul(t1, t->data.oper.right); /* t1 is now first term */ - TreeKill(t2); - t2=TreeCreate(); - - TreeCpy(t2, t->data.oper.left); - TreePow(t2, t->data.oper.right); - t3=TreeCreate(); - TreeCpy(t3, t->data.oper.left); - TreeApplyFunc(&t3, Ln); - TreeMul(t2, t3); - TreeKill(t3); - t3=TreeCreate(); - TreeDerive(t3, t->data.oper.right, name); - TreeMul(t2, t3); /* t2 is now second term */ - TreeKill(t3); - TreeCpy(res, t1); - TreeKill(t1); - TreeAdd(res, t2); /* res is the final result */ - TreeKill(t2); - break; - } /* switch */ - break; - case Func: - u=t->data.func.right; - res->tag=Oper; - res->data.oper.op=Mul; - res->data.oper.left=TreeCreate(); - res->data.oper.right=TreeCreate(); - TreeDerive(res->data.oper.left, t->data.func.right, name); - switch (t->data.func.fun) { - case Exp: - res->data.oper.right->tag=Func; - res->data.oper.right->data.func.right=TreeCreate(); - TreeCpy(res->data.oper.right->data.func.right, t->data.func.right); - res->data.oper.right->data.func.fun=Exp; - break; - case Cos: - res->data.oper.right->tag=NegSign; - res->data.oper.right->data.right=TreeCreate(); - res->data.oper.right->data.right->tag=Func; - res->data.oper.right->data.right->data.func.right=TreeCreate(); - res->data.oper.right->data.right->data.func.fun=Sin; - TreeCpy(res->data.oper.right->data.right->data.func.right, - t->data.func.right); - break; - case Sin: - res->data.oper.right->tag=Func; - res->data.oper.right->data.func.fun=Cos; - res->data.oper.right->data.func.right=TreeCreate(); - TreeCpy(res->data.oper.right->data.func.right, t->data.func.right); - break; - case Cosh: - res->data.oper.right->tag=Func; - res->data.oper.right->data.func.fun=Sinh; - res->data.oper.right->data.func.right=TreeCreate(); - TreeCpy(res->data.oper.right->data.func.right, t->data.func.right); - break; - case Sinh: - res->data.oper.right->tag=Func; - res->data.oper.right->data.func.fun=Cosh; - res->data.oper.right->data.func.right=TreeCreate(); - TreeCpy(res->data.oper.right->data.func.right, t->data.func.right); - break; - case Atan: /* u'/(1+u^2) */ - res->data.oper.op=Div; - res->data.oper.right=Op(Add, Const(1.0), Op(Pow, Copy(u), Const(2.0))); - break; - case Atanh: /* u'/(1-u^2) */ - res->data.oper.op=Div; - res->data.oper.right=Op(Sub, Const(1.0), Op(Pow, Copy(u), Const(2.0))); - break; - case Asinh: /* u'/(u^2+1)^0.5 */ - res->data.oper.op=Div; - res->data.oper.right=Op(Pow, Op(Add, Op(Pow, Copy(u), Const(2.0)), - Const(1.0)), Const(0.5)); - break; - case Acosh: /* u'/(u^2-1)^0.5 */ - res->data.oper.op=Div; - res->data.oper.right=Op(Pow, Op(Sub, Op(Pow, Copy(u), Const(2.0)), - Const(1.0)), Const(0.5)); - break; - case Tan: /* u'/cos(u)^2 */ - res->data.oper.op=Div; - res->data.oper.right=Op(Pow, Fun(Cos, Copy(u)), Const(2.0)); - break; - case Tanh: /* u'/cosh(u)^2 */ - res->data.oper.op=Div; - res->data.oper.right=Op(Pow, Fun(Cosh, Copy(u)), Const(2.0)); - break; - case Asin: /* u'/(1-u^2)^0.5 */ - res->data.oper.op=Div; - res->data.oper.right=Op(Pow, Op(Sub, Const(1.0), - Op(Pow, Copy(u), Const(2.0))), Const(0.5)); - break; - case Acos: /* -u'/(1-u^2)^0.5 */ - res->data.oper.op=Div; - res->data.oper.left=Neg(res->data.oper.left); - res->data.oper.right=Op(Pow, Op(Sub, Const(1.0), - Op(Pow, Copy(u), Const(2.0))), Const(0.5)); - break; - case Ln: - res->data.oper.right->tag=Oper; - res->data.oper.right->data.oper.op=Div; - res->data.oper.right->data.oper.left=TreeCreate(); - res->data.oper.right->data.oper.right=TreeCreate(); - res->data.oper.right->data.oper.left->tag=Konst; - res->data.oper.right->data.oper.left->data.value=1.0; - TreeCpy(res->data.oper.right->data.oper.right, t->data.func.right); - break; - case Log: - res->data.oper.right->tag=Oper; - res->data.oper.right->data.oper.op=Div; - res->data.oper.right->data.oper.left=TreeCreate(); - res->data.oper.right->data.oper.right=TreeCreate(); - res->data.oper.right->data.oper.left->tag=Konst; - res->data.oper.right->data.oper.left->data.value=0.4342944819; - TreeCpy(res->data.oper.right->data.oper.right, t->data.func.right); - break; - default: - break; - }; /* switch */ - break; /* Functions */ - case NegSign: - res->tag=NegSign; - res->data.right=TreeCreate(); - TreeDerive(res->data.right, t->data.right, name); - break; - }; /* switch */ - TreeReduce(res); - }; /* if */ + if (t==NULL) + return Const(0.0); + switch (t->tag) { + case Konst: + res=Const(0.0); + break; + case Var: + res=Const((strcmp(t->data.name, name)==0) ? 1.0 : 0.0); + break; + case Oper: + f=t->data.oper.left; + g=t->data.oper.right; + switch (t->data.oper.op) { + case Add: + res=Op(Add, TreeDerive(f, name), TreeDerive(g, name)); + break; + case Sub: + res=Op(Sub, TreeDerive(f, name), TreeDerive(g, name)); + break; + case Mul: /* f'*g + f*g' */ + res=Op(Add, Op(Mul, TreeDerive(f, name), g), + Op(Mul, f, TreeDerive(g, name))); + break; + case Div: /* (g*f' - f*g')/g^2 */ + res=Op(Div, Op(Sub, Op(Mul, g, TreeDerive(f, name)), + Op(Mul, f, TreeDerive(g, name))), Op(Pow, g, Const(2.0))); + break; + case Pow: /* g*f^(g-1)*f' + f^g*ln(f)*g' */ + res=TreeAdd(TreeMul(TreeMul(TreePow(f, TreeSub(g, Const(1.0))), + TreeDerive(f, name)), g), + TreeMul(TreeMul(TreePow(f, g), TreeApplyFunc(Ln, f)), + TreeDerive(g, name))); + break; + } + break; + case Func: + u=t->data.func.right; + du=TreeDerive(u, name); + switch (t->data.func.fun) { + case Exp: res=Op(Mul, du, Fun(Exp, u)); break; + case Sin: res=Op(Mul, du, Fun(Cos, u)); break; + case Cos: res=Op(Mul, du, Neg(Fun(Sin, u))); break; + case Sinh: res=Op(Mul, du, Fun(Cosh, u)); break; + case Cosh: res=Op(Mul, du, Fun(Sinh, u)); break; + case Ln: res=Op(Mul, du, Op(Div, Const(1.0), u)); break; + case Log: res=Op(Mul, du, Op(Div, Const(0.4342944819), u)); break; + case Tan: res=Op(Div, du, Op(Pow, Fun(Cos, u), Const(2.0))); break; + case Tanh: res=Op(Div, du, Op(Pow, Fun(Cosh, u), Const(2.0))); break; + case Atan: res=Op(Div, du, Op(Add, Const(1.0), Op(Pow, u, Const(2.0)))); + break; + case Atanh: res=Op(Div, du, Op(Sub, Const(1.0), Op(Pow, u, Const(2.0)))); + break; + case Asinh: res=Op(Div, du, Op(Pow, Op(Add, Op(Pow, u, Const(2.0)), + Const(1.0)), Const(0.5))); + break; + case Acosh: res=Op(Div, du, Op(Pow, Op(Sub, Op(Pow, u, Const(2.0)), + Const(1.0)), Const(0.5))); + break; + case Asin: res=Op(Div, du, Op(Pow, Op(Sub, Const(1.0), + Op(Pow, u, Const(2.0))), Const(0.5))); + break; + case Acos: res=Op(Div, Neg(du), Op(Pow, Op(Sub, Const(1.0), + Op(Pow, u, Const(2.0))), Const(0.5))); + break; + } + break; + case NegSign: + res=Neg(TreeDerive(t->data.right, name)); + break; + } + return Reduce(res); } /* TreeDerive */ double TreeEval(Tree t) { @@ -954,7 +469,7 @@ double TreeEval(Tree t) { /* The following procedure is 'internal' */ -void TreePrintXtra(Tree t, int mode, FILE *output) { +static void TreePrintXtra(Tree t, int mode, FILE *output) { /* Mode: 1 - (HP) Fortran 77 */ /* 2 - (HP) Pascal */ @@ -1426,82 +941,3 @@ void TreePrint(Tree t, int mode, FILE *output) { len=10; TreePrintXtra(t, mode, output); } /* TreePrint */ - -void TreeCpy(Tree res, Tree t) { - - if (t==NULL) { - res=NULL; - tree_error=NoTree; - } /* if */ - else { - switch (t->tag) { - case Oper: - res->tag=Oper; - res->data.oper.left=TreeCreate(); - res->data.oper.right=TreeCreate(); - res->data.oper.op=t->data.oper.op; - TreeCpy(res->data.oper.left, t->data.oper.left); - TreeCpy(res->data.oper.right, t->data.oper.right); - break; - case Konst: - res->tag=Konst; - res->data.value=t->data.value; - break; - case Var: - res->tag=Var; - (void) strcpy(res->data.name, t->data.name); - break; - case Func: - res->tag=Func; - res->data.func.fun=t->data.func.fun; - res->data.func.right=TreeCreate(); - TreeCpy(res->data.func.right, t->data.func.right); - break; - case NegSign: - res->tag=NegSign; - res->data.right=TreeCreate(); - TreeCpy(res->data.right, t->data.right); - break; - }; /* switch */ - }; /* else */ -} /* TreeCpy */ - -void TreeKill(Tree t) { - - if (t!=NULL) { - switch (t->tag) { - case Oper: - TreeKill(t->data.oper.left); - TreeKill(t->data.oper.right); - break; - case Var: - break; - case Func: - TreeKill(t->data.func.right); - break; - case NegSign: - TreeKill(t->data.right); - break; - default: - break; - } - free(t); - } -} /* TreeKill */ - -void TreeApplyFunc(Tree *t, Function fun) { - - Tree temp; - - temp=TreeCreate(); - temp->tag=Func; - temp->data.func.fun=fun; - temp->data.func.right=TreeCreate(); - TreeCpy(temp->data.func.right, *t); - TreeReduce(temp); - TreeKill(*t); - *t=TreeCreate(); - TreeCpy(*t, temp); - TreeKill(temp); - tree_error=0; -} /* TreeApplyFunc */ diff --git a/src/symbmath.h b/src/symbmath.h index 3ab3c41..632ffd5 100644 --- a/src/symbmath.h +++ b/src/symbmath.h @@ -1,4 +1,4 @@ -/**************************************************************************** +/**************************************************************************** Symbolic mathematics in ANSI-C. CopyWrong 1992-1994 by @@ -11,7 +11,9 @@ See kc.tex for details. - Last updated: 27 September 1994 + Expression trees are immutable: every operation returns a new tree and + shares the subtrees of its arguments. All nodes are allocated from one + arena, which TreeFreeAll releases; there is no per-tree free. ****************************************************************************/ #ifndef _SYMBMATH_ @@ -35,36 +37,32 @@ struct TreeCell { char name[STRING_LENGTH]; /* variable */ struct { TreeOper op; - struct TreeCell *left, *right; + const struct TreeCell *left, *right; } oper; /* operation */ struct { Function fun; - struct TreeCell *right; + const struct TreeCell *right; } func; - struct TreeCell *right; /* negative sign */ + const struct TreeCell *right; /* negative sign */ } data; }; typedef struct TreeCell TreeNode; -typedef TreeNode *Tree; - -extern int tree_error, len, left, right; +typedef const TreeNode *Tree; extern int TreeGetError(void); -extern Tree TreeCreate(void); -extern void TreeAdd(Tree, Tree); -extern void TreeSub(Tree, Tree); -extern void TreeMul(Tree, Tree); -extern void TreeDiv(Tree, Tree); -extern void TreePow(Tree, Tree); -extern void TreeSign(Tree); -extern void TreeAssignConst(Tree, double); -extern void TreeAssignVar(Tree, char *); -extern void TreeSubstVar(Tree, char *, double); -extern void TreeDerive(Tree, Tree, char *); +extern Tree TreeConst(double); +extern Tree TreeVar(const char *); +extern Tree TreeAdd(Tree, Tree); +extern Tree TreeSub(Tree, Tree); +extern Tree TreeMul(Tree, Tree); +extern Tree TreeDiv(Tree, Tree); +extern Tree TreePow(Tree, Tree); +extern Tree TreeSign(Tree); +extern Tree TreeApplyFunc(Function, Tree); +extern Tree TreeSubstVar(Tree, const char *, double); +extern Tree TreeSubstTree(Tree, const char *, Tree); +extern Tree TreeDerive(Tree, const char *); extern double TreeEval(Tree); extern void TreePrint(Tree, int, FILE *); -extern void TreeCpy(Tree, Tree); -extern void TreeKill(Tree); -extern void TreeSubstTree(Tree, char *, Tree); -extern void TreeApplyFunc(Tree *, Function); +extern void TreeFreeAll(void); #endif diff --git a/src/tableman.c b/src/tableman.c index e7e8951..dbac29e 100644 --- a/src/tableman.c +++ b/src/tableman.c @@ -340,6 +340,13 @@ void NewPowerConst(int react_no, char *name, double charge, } /* while */ } /* NewPowerConst */ +/* A missing tree reads as 0, like the empty node the old copying API + left behind. */ +static Tree OrZero(Tree t) { + + return (t!=NULL) ? t : TreeConst(0.0); +} /* OrZero */ + void NewRateConst(int react, int direct, Tree value) { /* For direct: -1 = >, 0 = =, 1 = < */ @@ -353,8 +360,7 @@ void NewRateConst(int react, int direct, Tree value) { switch (reacttable[i].react_tag) { case uni: if (direct==-1) { - reacttable[i].t1=TreeCreate(); - TreeCpy(reacttable[i].t1, value); + reacttable[i].t1=value; reacttable[i].sel1=1; error=NoError; } /* if */ @@ -363,14 +369,12 @@ void NewRateConst(int react, int direct, Tree value) { break; case bi: if (direct==-1) { - reacttable[i].t1=TreeCreate(); - TreeCpy(reacttable[i].t1, value); + reacttable[i].t1=value; reacttable[i].sel1=1; error=NoError; } /* if */ else if (direct==1) { - reacttable[i].t2=TreeCreate(); - TreeCpy(reacttable[i].t2, value); + reacttable[i].t2=value; reacttable[i].sel2=1; error=NoError; } /* else-if */ @@ -379,8 +383,7 @@ void NewRateConst(int react, int direct, Tree value) { break; case equi: if (direct==0) { - reacttable[i].t1=TreeCreate(); - TreeCpy(reacttable[i].t1, value); + reacttable[i].t1=value; reacttable[i].sel1=1; error=NoError; } /* if */ @@ -407,8 +410,7 @@ void NewRateExpr(int react, int direct, Tree value) { switch (reacttable[i].react_tag) { case uni: if (direct==-1) { - reacttable[i].t1=TreeCreate(); - TreeCpy(reacttable[i].t1, value); + reacttable[i].t1=value; reacttable[i].sel1=2; error=NoError; } /* if */ @@ -417,14 +419,12 @@ void NewRateExpr(int react, int direct, Tree value) { break; case bi: if (direct==-1) { - reacttable[i].t1=TreeCreate(); - TreeCpy(reacttable[i].t1, value); + reacttable[i].t1=value; reacttable[i].sel1=2; error=NoError; } /* if */ else if (direct==1) { - reacttable[i].t2=TreeCreate(); - TreeCpy(reacttable[i].t2, value); + reacttable[i].t2=value; reacttable[i].sel2=2; error=NoError; } /* else-if */ @@ -787,7 +787,7 @@ Direc GetReactKind(int react_no) { return reacttable[i].react_tag; } /* GetReactKind */ -void GetRateConst(int react_no, Direc direct, int way, Tree res) { +Tree GetRateConst(int react_no, Direc direct, int way) { /**** way is only used when direct==bi, @@ -806,16 +806,12 @@ void GetRateConst(int react_no, Direc direct, int way, Tree res) { else i++; } /* while */ - if (direct==bi) - if (way==1) - TreeCpy(res, reacttable[i].t1); - else - TreeCpy(res, reacttable[i].t2); - else - TreeCpy(res, reacttable[i].t1); + if ((direct==bi) && (way!=1)) + return OrZero(reacttable[i].t2); + return OrZero(reacttable[i].t1); } /* GetRateConst */ -void GetRateExpr(int react_no, Direc direct, int way, Tree t) { +Tree GetRateExpr(int react_no, Direc direct, int way) { /**** way is only used when direct==bi, @@ -834,13 +830,9 @@ void GetRateExpr(int react_no, Direc direct, int way, Tree t) { else i++; } /* while */ - if (direct==bi) - if (way==1) - TreeCpy(t, reacttable[i].t1); - else - TreeCpy(t, reacttable[i].t2); - else - TreeCpy(t, reacttable[i].t1); + if ((direct==bi) && (way!=1)) + return OrZero(reacttable[i].t2); + return OrZero(reacttable[i].t1); } /* GetRateExpr */ int GetRateKind(int react_no, Direc direct, int way) { @@ -978,8 +970,7 @@ void NewExpr(char *name, Tree t) { } /* while */ if (found==0) { strcpy(exprtable[expr_last].name, name); - exprtable[expr_last].expr=TreeCreate(); - TreeCpy(exprtable[expr_last].expr, t); + exprtable[expr_last].expr=t; expr_last++; error=NoError; } /* if */ @@ -991,17 +982,15 @@ int NumOfExpr(void) { return expr_last; } /* NumOfExpr */ -void GetExprNo(int no, char *name, Tree t) { +Tree GetExprNo(int no, char *name) { if (no>expr_last) { error=NotFound; - t=NULL; + return OrZero(NULL); } /* if */ - else { - error=NoError; - strcpy(name, exprtable[no-1].name); - TreeCpy(t, exprtable[no-1].expr); - } /* else */ + error=NoError; + strcpy(name, exprtable[no-1].name); + return exprtable[no-1].expr; } /* GetExprNo */ int IsVarParameter(char *name) { @@ -1029,9 +1018,8 @@ void NewConstraint(char *name, double charge, Tree t) { if (con_last==ConstrainSize) error=TooManyConstrain; else { - contable[con_last].expr=TreeCreate(); + contable[con_last].expr=t; strcpy(contable[con_last].name, name); - TreeCpy(contable[con_last].expr, t); contable[con_last].charge=charge; con_last++; error=NoError; @@ -1043,18 +1031,16 @@ int NumOfConstraint(void) { return con_last; } /* NumOfConstraint */ -void GetConstraintNo(int no, char *name, double *charge, Tree t) { +Tree GetConstraintNo(int no, char *name, double *charge) { if (no>con_last) { error=NotFound; - t=NULL; + return OrZero(NULL); } /* if */ - else { - strcpy(name, contable[no-1].name); - *charge=contable[no-1].charge; - error=NoError; - TreeCpy(t, contable[no-1].expr); - } /* else */ + strcpy(name, contable[no-1].name); + *charge=contable[no-1].charge; + error=NoError; + return contable[no-1].expr; } /* GetConstraintNo */ int IsSpecInConstraint(char *name, double charge) { diff --git a/src/tableman.h b/src/tableman.h index 4f513d1..4612aa0 100644 --- a/src/tableman.h +++ b/src/tableman.h @@ -175,8 +175,8 @@ extern double GetCoeffInReact(int, char *, double, int); extern double GetPowConstInReact(int, char *, double, int); extern void GetSpecNo(int, char *, double *); extern Direc GetReactKind(int); -extern void GetRateConst(int, Direc, int, Tree); -extern void GetRateExpr(int, Direc, int, Tree); +extern Tree GetRateConst(int, Direc, int); +extern Tree GetRateExpr(int, Direc, int); extern int GetRateKind(int, Direc, int); extern int NoOfReact(void); extern void NewCoeff(int, char *, double, double, int); @@ -189,12 +189,12 @@ extern int NumOfDynVar(void); extern void GetDynVarNo(int, char *); extern void NewExpr(char *, Tree); extern int NumOfExpr(void); -extern void GetExprNo(int, char *, Tree); +extern Tree GetExprNo(int, char *); extern int IsVarParameter(char *); extern void NewPowerConst(int, char *, double, double, int); extern void NewConstraint(char *, double, Tree); extern int NumOfConstraint(void); -extern void GetConstraintNo(int, char *, double *, Tree); +extern Tree GetConstraintNo(int, char *, double *); extern int IsSpecInConstraint(char *, double); extern void NewSpecConst(char *, double, char *, double); extern double GetSpecConst(char *, double, char *); From 2150412e5b086df3764e9b2e13ddb5e7ac3d71ff Mon Sep 17 00:00:00 2001 From: Kenneth Geisshirt Date: Sat, 31 Oct 2026 19:19:26 +0100 Subject: [PATCH 09/13] Mode 5: assign dynamical variables in djacobian The header of the generated djacobian procedure assigned the last species again instead of each dynamical variable, at index i+NoOfSpec()/NumOfConstraint(): a typo for "-" that divides by zero in models without constraints. It now matches the other procedures, e.g. z:=xx_[3] instead of B:=xx_[1] in the hessian test model. Co-Authored-By: Claude Opus 5.5 --- src/kncont.c | 3 +-- test/expected/hessian.des.m5/kcm5proc.p | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/kncont.c b/src/kncont.c index 90a8490..dc9156c 100644 --- a/src/kncont.c +++ b/src/kncont.c @@ -109,8 +109,7 @@ void KnCont(FILE *pcode, FILE *hcode) { } /* for i */ for(i=1; i<=NumOfDynVar(); i++) { GetDynVarNo(i, name); - fprintf(pcode, "%s:=xx_[%d];\n", rename, - i+NoOfSpec()/NumOfConstraint()); + fprintf(pcode, "%s:=xx_[%d];\n", name, i+NoOfSpec()-NumOfConstraint()); } /* for i */ need_dd_jac=0; diff --git a/test/expected/hessian.des.m5/kcm5proc.p b/test/expected/hessian.des.m5/kcm5proc.p index f9dd319..68fb35a 100644 --- a/test/expected/hessian.des.m5/kcm5proc.p +++ b/test/expected/hessian.des.m5/kcm5proc.p @@ -7,7 +7,7 @@ PROCEDURE djacobian(xx_:glnarray; VAR dS_:gldjacobian); BEGIN A:=xx_[1]; B:=xx_[2]; -B:=xx_[1]; +z:=xx_[3]; dS_[1,1,1]:=0.000000e+00; dS_[1,1,2]:=0.000000e+00; dS_[1,1,3]:=0.000000e+00; From b6d9698c4b6352d302dd010bf8883f47124621a9 Mon Sep 17 00:00:00 2001 From: Kenneth Geisshirt Date: Sat, 31 Oct 2026 19:20:26 +0100 Subject: [PATCH 10/13] Free the temporary arrays of GenerateRateExpr v_store and r hold pointers only; the trees they point to live in the arena and stay referenced from v, rfw and rrv. Co-Authored-By: Claude Opus 5.5 --- src/codegen.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/codegen.c b/src/codegen.c index 16fc073..3f6b076 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -231,6 +231,8 @@ void GenerateRateExpr(void) { for(i=0; i<(NoOfSpec()-NumOfConstraint()+NumOfDynVar()); i++) v[i]=v_store[i]; + free(v_store); + free(r); StringFree(name); StringFree(rename); } /* GenerateRateExpr */ From b43799a993cca98165a1b166e4c7d43170f65c85 Mon Sep 17 00:00:00 2001 From: Kenneth Geisshirt Date: Sat, 31 Oct 2026 19:52:52 +0100 Subject: [PATCH 11/13] Free the name buffers of modes 1, 4 and 5 Mixed never freed name and rename. ConIS and KnCont allocated them before a parameter check that returns early; they now allocate them after it. LeakSanitizer reported these on every model. Co-Authored-By: Claude Opus 5.5 --- src/conis.c | 5 +++-- src/kncont.c | 5 +++-- src/mixed.c | 2 ++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/conis.c b/src/conis.c index 33542fd..430b20c 100644 --- a/src/conis.c +++ b/src/conis.c @@ -34,8 +34,6 @@ void ConIS(FILE *fcode) { int i, j, constraint, dyn, form; int NumbOfParams, NumbOfDynVars; - name=StringAlloc(); - rename=StringAlloc(); timer=time(&timer); NumbOfParams=NumOfParameter(); NumbOfDynVars=NoOfSpec()-NumOfConstraint()+NumOfDynVar(); @@ -43,6 +41,9 @@ void ConIS(FILE *fcode) { fprintf(stderr, "Continuation program aborted: Wrong number of parameters - should be between 2 and 40.\n"); return; } /* if */ + + name=StringAlloc(); + rename=StringAlloc(); InitCodeGenVar(NoOfSpec()+NumOfDynVar()-NumOfConstraint(), NumOfConstraint(), NoOfReact()); diff --git a/src/kncont.c b/src/kncont.c index dc9156c..88d81cf 100644 --- a/src/kncont.c +++ b/src/kncont.c @@ -35,8 +35,6 @@ void KnCont(FILE *pcode, FILE *hcode) { int NumbOfParams, NumbOfDynVars; int need_dd_jac=0, BfErrorCode; - name=StringAlloc(); - rename=StringAlloc(); timer=time(&timer); NumbOfParams=NumOfParameter(); NumbOfDynVars=NoOfSpec()-NumOfConstraint()+NumOfDynVar(); @@ -45,6 +43,9 @@ void KnCont(FILE *pcode, FILE *hcode) { return; } /* if */ + name=StringAlloc(); + rename=StringAlloc(); + InitCodeGenVar(NoOfSpec()+NumOfDynVar()-NumOfConstraint(), NumOfConstraint(), NoOfReact()); GenerateRateExpr(); diff --git a/src/mixed.c b/src/mixed.c index 660324c..35d455e 100644 --- a/src/mixed.c +++ b/src/mixed.c @@ -366,4 +366,6 @@ void Mixed(void) { MatrixFree(num_of_reac,reacfwds_); MatrixFree(num_of_reac,reacrvds_); } + StringFree(name); + StringFree(rename); } /* Mixed */ From ec43c68b82401a3046f50780d42d699ad8883b4d Mon Sep 17 00:00:00 2001 From: Kenneth Geisshirt Date: Sat, 31 Oct 2026 19:21:02 +0100 Subject: [PATCH 12/13] CI: run the test suite with sanitizers One more matrix entry builds kc with KC_SANITIZE on Linux/clang, where LeakSanitizer is available, so memory errors, leaks and undefined behaviour fail the build. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/ci.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 589a602..9fdc777 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,7 +6,7 @@ on: jobs: test: - name: ${{ matrix.os }} / ${{ matrix.cc }} / C${{ matrix.std }} + name: ${{ matrix.os }} / ${{ matrix.cc }} / C${{ matrix.std }}${{ matrix.sanitize && ' / sanitizers' || '' }} runs-on: ${{ matrix.os }} strategy: fail-fast: false @@ -17,6 +17,7 @@ jobs: - { os: ubuntu-latest, cc: gcc, std: 23 } - { os: macos-latest, cc: clang, std: 17 } - { os: macos-latest, cc: gcc-14, std: 17 } + - { os: ubuntu-latest, cc: clang, std: 17, sanitize: ON } env: CC: ${{ matrix.cc }} steps: @@ -25,7 +26,7 @@ jobs: if: runner.os == 'Linux' run: sudo apt-get update && sudo apt-get install -y flex bison - name: Configure - run: cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_STANDARD=${{ matrix.std }} -DCMAKE_C_FLAGS=-Werror + run: cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_STANDARD=${{ matrix.std }} -DCMAKE_C_FLAGS=-Werror -DKC_SANITIZE=${{ matrix.sanitize || 'OFF' }} - name: Build run: cmake --build build -j4 - name: Test @@ -34,5 +35,5 @@ jobs: if: failure() uses: actions/upload-artifact@v4 with: - name: test-work-${{ matrix.os }}-${{ matrix.cc }}-c${{ matrix.std }} + name: test-work-${{ matrix.os }}-${{ matrix.cc }}-c${{ matrix.std }}${{ matrix.sanitize && '-sanitize' || '' }} path: build/test-work From 92e9e312666a9d093d715f8d9afb60fad44bac93 Mon Sep 17 00:00:00 2001 From: Kenneth Geisshirt Date: Sat, 31 Oct 2026 19:21:25 +0100 Subject: [PATCH 13/13] Document the tree redesign, the fixes and KC_SANITIZE Co-Authored-By: Claude Opus 5.5 --- CHANGES.md | 27 +++++++++++++++++++++++++++ README.md | 9 +++++++++ TODO.md | 1 - 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index e5e5c64..dfc5eda 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -21,6 +21,13 @@ current C compilers, and an automated test suite has been added. depend on the compiler or CPU. * Legacy material (retired generators, DOS copies, platform Makefiles, site-specific scripts) has been removed. It remains in git history. +* Expression trees are immutable and allocated from an arena: every + operation returns a new tree that shares its arguments instead of + copying them. This removes the memory leaks of the old copying API + and shrinks `symbmath.c` by about 600 lines. The generated code is + unchanged. +* The CMake option `KC_SANITIZE` builds kc with AddressSanitizer and + UndefinedBehaviorSanitizer. ### Tests @@ -29,6 +36,10 @@ current C compilers, and an automated test suite has been added. mode 3 simulations. Models that kc must reject are tested too. * GitHub Actions runs the suite on Linux (GCC, clang, C23) and macOS (clang, GCC 14). + One more Linux job runs it with sanitizers. +* New test models cover the derivatives of all functions + (`derivatives1`, `derivatives2`) and second and third derivatives by + dynamical variables in mode 5 (`hessian`). ### Changed results @@ -37,6 +48,11 @@ current C compilers, and an automated test suite has been added. reported a failure in `hqr2`, and D3 printed all-zero eigenvectors. The eigenvector output (mostly normalization and sign) changes for 16 models. +* Reducing `f+(-g)` and `f-(-g)` kept the negation, so the sign of `g` + flipped every time the expression was reduced. Single Jacobian + entries of gtf and shn90 had the wrong value, which changes their + mode 1 eigenvalues and mode 3 end states. In other models only the + printed form changes, e.g. `x+(-(y))` is now `x-y`. ### Bug fixes @@ -64,3 +80,14 @@ current C compilers, and an automated test suite has been added. result of `TreeEval` and table lookups of unknown names. * The warning for an unknown command-line option printed the wrong character. +* Derivatives of functions: ln gave 0, tan and tanh gave `u'/(u*2)`, + asinh gave `u'`, acosh was not implemented and acos crashed kc. +* `asinh`, `acosh` and `atanh` of constants evaluated to their + argument. +* Mode 2: the initial values in `in.dat` were shifted by one species; + the first one was read out of bounds. +* Mode 5: second and third derivatives by dynamical variables were + stored in the wrong slot, which made kc crash on models with two + parameters and a dynamical variable. The `djacobian` procedure + assigned the wrong variables, with a division by zero in models + without constraints. diff --git a/README.md b/README.md index 28da4b1..018c4cd 100644 --- a/README.md +++ b/README.md @@ -187,6 +187,15 @@ compared as well, so error handling is tested too. intended change of the output, rewrite the expected files with `KC_UPDATE=1 ctest --test-dir build` and review the diff. +To check kc for memory errors, leaks and undefined behaviour, build it with +sanitizers (leaks are only detected on Linux): + +```sh +cmake -B build-sanitize -DKC_SANITIZE=ON +cmake --build build-sanitize +ctest --test-dir build-sanitize -j8 +``` + ## Legal issues The program is copyrighted in the sense of GNU General Public License diff --git a/TODO.md b/TODO.md index 4e4a983..0bfe422 100644 --- a/TODO.md +++ b/TODO.md @@ -5,7 +5,6 @@ following list shows with which priority different subject should be done: * Better reduction of expressions. -* Better memory allocation (especially in `symbmath.{c,h}`). * Better documentation, both user's and programmer's manual. * Reorganise the table manager. * Rewrite the grammar, i.e. better error recovery and many more consistency checks.