├── 1OL-H2O.DAT ├── ACET-1OL.DAT ├── ACET-CHCL3.DAT ├── ACET-CHCL3.xlsx ├── ACET-H2O.DAT ├── Acet-CHCl3-meth.DAT ├── Acet-CHCl3-meth150.xlsx ├── Acet-CHCl3-meth36.xlsx ├── AntoineGet.m ├── AntoineTable.mat ├── AntoineTableBrowse.m ├── BB_ALL.mat ├── CHCL3-METH.xlsx ├── FIT_FUNCTION_FORUNIQUAC_FAST.m ├── FIT_function_flex.m ├── FIT_function_flexTP.m ├── FIT_function_flexTP_meshgrid.m ├── Fit_function.m ├── Fit_functionT.m ├── Fit_function_TERN.m ├── Fit_function_TERN2.m ├── IMPORT_QUERN_WITH_GAMMA.m ├── LMFsolve.m ├── LMFsolveOLD.m ├── LMFsolvetest.m ├── LevenbergMarquardt.m ├── METH-ACET.xlsx ├── NONuniMUTA.m ├── Psat.m ├── README.md ├── START_HERE.m ├── TERNARY.DAT ├── TERNARY_revised.DAT ├── Tsat.m ├── benz_propylAlcho.xlsx ├── bisection.m ├── classicsolver.m ├── classicsolver[Conflict].m ├── compare2.xlsx ├── comparison_auto_save.m ├── dokimes_gaTERN.m ├── dokimes_ga_test4b.m ├── dokimes_ga_test4b_MONO.m ├── dokimes_ga_test4b_ace_water.m ├── dokimespop.m ├── fminsearchhyper3.mat ├── ga_TERN_fast.m ├── ga_test4b.m ├── ga_test4bT.m ├── ga_test4b_TERN.m ├── ga_test4b_TERN_STOP1.m ├── ga_test4c.m ├── ga_test4c_TERN.m ├── ga_test5_TERN.m ├── gamma_uniquac.m ├── gammacalc.m ├── hybrid_ga_fminsearch1.m ├── hybrid_ga_fminsearch1_TP.m ├── hybrid_ga_fminsearch_old.m ├── importfile.m ├── importfile1.m ├── importfile2.m ├── importfileTERN_excel.m ├── importfile_EXCEL.m ├── importfile_QUAD_EXCEL.m ├── insert_TERN_TP.m ├── insert_data_BENZ_ISOPRO_T.m ├── insert_data__acetone_meth.m ├── insert_data__acetone_meth2.m ├── insert_data__acetone_meth2_TP.m ├── insert_data__acetone_meth_TP.m ├── insert_data_acet_chcl3.m ├── insert_data_acet_chcl3_TP.m ├── insert_data_acetone_water.m ├── insert_data_acetone_water_TP.m ├── insert_data_chcl3_meth.m ├── insert_data_chcl3_meth_TP.m ├── insert_data_exp_TERNSET2_150_TP.m ├── insert_data_exp_TERNset1.m ├── insert_data_exp_TERNset1_TP.m ├── insert_data_exp_TERNset2_150.m ├── insert_data_exp_TERNset2_36.m ├── insert_data_meth_ater.m ├── insert_data_meth_water_TP.m ├── insert_inglesiasTP.m ├── insert_quaternary1.m ├── lastexplore.m ├── levmar.m ├── lsqnonlinmine.m ├── matlabbig.mat ├── myfminimax.m ├── myfminsearch.m ├── option_clas_solver.mat ├── optionfminimax.mat ├── petama.m ├── props.mat ├── propsTableBrowse.m ├── quaternary.pdf ├── quaternary1.xlsx ├── quaternary1_GAMMA.xlsx ├── readme.txt ├── rosen.m ├── rouletteDU.m ├── run_GA.m ├── surface_uniq.m ├── test3m.m ├── test_runTERN.mat ├── testforhyper.m ├── uniquac.m └── uniquac_fast.m /1OL-H2O.DAT: -------------------------------------------------------------------------------- 1 | System: METHANOL(1) - WATER(2) 2 | 3 | T(K) P(bar) Y(1) X(1) 4 | 373.1500 1.0411 0.0192 0.0022 5 | 373.1500 1.1032 0.0860 0.0110 6 | 373.1500 1.2411 0.1910 0.0350 7 | 373.1500 1.3376 0.2450 0.0530 8 | 373.1500 1.4272 0.3130 0.0740 9 | 373.1500 1.6478 0.4340 0.1210 10 | 373.1500 1.7651 0.4960 0.1630 11 | 373.1500 2.0477 0.6190 0.2810 12 | 373.1500 2.1650 0.6620 0.3520 13 | 373.1500 2.5097 0.7500 0.5220 14 | 373.1500 2.7096 0.7920 0.6060 15 | 373.1500 2.8200 0.8240 0.6670 16 | 373.1500 3.1164 0.9110 0.8260 17 | 373.1500 3.3440 0.9690 0.9320 18 | 373.1500 3.3715 0.9760 0.9460 19 | 373.1500 3.3715 0.9810 0.9580 20 | -------------------------------------------------------------------------------- /ACET-1OL.DAT: -------------------------------------------------------------------------------- 1 | System: ACETONE(1) - METHANOL(2) 2 | 3 | T(K) P(bar) Y(1) X(1) 4 | 5 | 373.1500 3.5232 0.0700 0.0470 6 | 373.1500 3.5646 0.0930 0.0680 7 | 373.1500 3.7576 0.1870 0.1460 8 | 373.1500 3.7921 0.2580 0.2200 9 | 373.1500 4.0128 0.4170 0.3970 10 | 373.1500 4.0265 0.5070 0.5070 11 | 373.1500 4.0265 0.5470 0.5620 12 | 373.1500 4.0265 0.5980 0.6240 13 | 373.1500 4.0128 0.6140 0.6410 14 | 373.1500 4.0196 0.6350 0.6600 15 | 373.1500 3.9576 0.7110 0.7470 16 | 373.1500 3.8542 0.8190 0.8700 17 | 373.1500 3.7507 0.9170 0.9520 18 | 373.1500 3.6818 0.9500 0.9770 19 | -------------------------------------------------------------------------------- /ACET-CHCL3.DAT: -------------------------------------------------------------------------------- 1 | System: ACETONE(1) - CHLOROFORM(2) 2 | T(K) P(mmHg) X(1) Y(1) 3 | 323.15 519 0 0 4 | 323.15 513.8 0.023 0.0086 5 | 323.15 507.3 0.05 0.0201 6 | 323.15 497.9 0.09 0.0408 7 | 323.15 495.4 0.1 0.0464 8 | 323.15 487 0.135 0.0719 9 | 323.15 483.2 0.152 0.0863 10 | 323.15 481.2 0.16 0.0935 11 | 323.15 470.8 0.204 0.1383 12 | 323.15 464.3 0.236 0.176 13 | 323.15 461.2 0.25 0.193 14 | 323.15 456.6 0.3 0.2582 15 | 323.15 454.2 0.35 0.3382 16 | 323.15 454 0.364 0.3608 17 | 323.15 454.1 0.368 0.3675 18 | 323.15 454.3 0.39 0.4032 19 | 323.15 454.9 0.42 0.4511 20 | 323.15 457.8 0.45 0.4963 21 | 323.15 460.7 0.469 0.524 22 | 323.15 466.3 0.5 0.567 23 | 323.15 473.8 0.539 0.6211 24 | 323.15 476 0.55 0.637 25 | 323.15 486.4 0.6 0.6978 26 | 323.15 489.1 0.612 0.7113 27 | 323.15 491.3 0.622 0.7222 28 | 323.15 497.9 0.65 0.7528 29 | 323.15 511.8 0.7 0.8028 30 | 323.15 527.2 0.75 0.8515 31 | 323.15 543.7 0.8 0.8955 32 | 323.15 561 0.85 0.9319 33 | 323.15 578.3 0.9 0.9614 34 | 323.15 595.8 0.95 0.9829 35 | 323.15 613 1 1 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /ACET-CHCL3.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pngts/Nonlinear-parameter-estimation-in-thermodynamic-models/93bd1a062f616e61b0d7214b293b14d48dd16c81/ACET-CHCL3.xlsx -------------------------------------------------------------------------------- /ACET-H2O.DAT: -------------------------------------------------------------------------------- 1 | System: ACETONE(1) - WATER (2) 2 | 3 | T(K) P(bar) Y(1) X(1) 4 | 5 | 373.1500 1.1101 0.0902 0.0033 6 | 373.1500 1.1307 0.1090 0.0040 7 | 373.1500 1.1721 0.1180 0.0045 8 | 373.1500 1.3031 0.2070 0.0080 9 | 373.1500 2.2408 0.5450 0.0480 10 | 373.1500 2.4476 0.6130 0.0820 11 | 373.1500 2.7855 0.6320 0.1080 12 | 373.1500 2.6683 0.6370 0.0980 13 | 373.1500 3.0682 0.7050 0.2200 14 | 373.1500 3.1992 0.7150 0.3080 15 | 373.1500 3.2061 0.7190 0.3160 16 | 373.1500 3.3371 0.7270 0.3970 17 | 373.1500 3.4267 0.7460 0.5260 18 | 373.1500 3.4750 0.7470 0.4800 19 | 373.1500 3.5715 0.8010 0.6960 20 | 373.1500 3.4956 0.8140 0.7150 21 | 373.1500 3.5991 0.8230 0.7420 22 | 373.1500 3.6266 0.8370 0.7710 23 | 373.1500 3.6749 0.8780 0.8540 24 | 373.1500 3.6887 0.9460 0.9440 25 | 373.1500 3.6818 0.9720 0.9710 26 | 373.1500 3.6887 0.9780 0.9770 27 | -------------------------------------------------------------------------------- /Acet-CHCl3-meth.DAT: -------------------------------------------------------------------------------- 1 | 150 2 | 3 | Acetone(1)/CHCl3(2)/methnaol(3) 4 | 5 | T (K) P(bar) y1 x1 y2 x2 6 | 323.15 .81793 .6499 .5995 .0204 .0309 7 | 323.15 .80725 .5974 .5207 .0200 .0269 8 | 323.15 .79355 .5502 .4500 .0194 .0232 9 | 323.15 .77968 .5126 .3953 .0189 .0204 10 | 323.15 .76368 .4701 .3387 .0183 .0175 11 | 323.15 .75048 .4388 .2998 .0178 .0155 12 | 323.15 .73599 .4098 .2662 .0168 .0135 13 | 323.15 .72122 .3729 .2275 .0161 .0117 14 | 323.15 .79691 .5617 .4675 .0201 .0247 15 | 323.15 .80348 .5842 .5017 .0203 .0265 16 | 323.15 .81000 .6106 .5411 .0206 .0286 17 | 323.15 .81611 .6414 .5872 .0208 .0310 18 | 323.15 .82140 .6792 .6422 .0211 .0339 19 | 323.15 .82459 .7246 .7042 .0215 .0372 20 | 323.15 .82369 .7850 .7782 .0219 .0411 21 | 323.15 .81840 .8448 .8414 .0224 .0444 22 | 323.15 .81208 .8903 .8833 .0228 .0466 23 | 323.15 .80776 .9168 .9054 .0231 .0478 24 | 323.15 .80412 .9370 .9213 .0232 .0486 25 | 323.15 .80120 .9538 .9338 .0234 .0493 26 | 323.15 .79841 .9644 .9415 .0235 .0497 27 | 323.15 .72537 .1998 .1511 .2132 .1420 28 | 323.15 .73341 .2113 .1680 .2242 .1580 29 | 323.15 .73937 .2221 .1847 .2338 .1737 30 | 323.15 .74650 .2375 .2095 .2464 .1969 31 | 323.15 .75279 .2543 .2380 .2596 .2239 32 | 323.15 .75622 .2712 .2663 .2709 .2504 33 | 323.15 .75736 .2900 .2971 .2824 .2794 34 | 323.15 .75506 .3128 .3315 .2947 .3118 35 | 323.15 .74821 .3414 .3690 .3082 .3470 36 | 323.15 .73470 .3778 .4076 .3241 .3834 37 | 323.15 .70565 .4334 .4507 .3471 .4239 38 | 323.15 .65472 .5265 .4960 .3863 .4666 39 | 323.15 .62991 .3397 .3528 .6054 .6297 40 | 323.15 .62976 .3793 .3813 .5641 .5998 41 | 323.15 .63123 .4197 .4103 .5221 .5693 42 | 323.15 .63531 .4723 .4483 .4682 .5295 43 | 323.15 .63997 .5108 .4767 .4289 .4997 44 | 323.15 .64991 .5701 .5220 .3685 .4521 45 | 323.15 .66377 .6290 .5697 .3090 .4020 46 | 323.15 .68326 .6922 .6252 .2453 .3438 47 | 323.15 .70696 .7535 .6854 .1848 .2806 48 | 323.15 .73230 .8059 .7437 .1332 .2194 49 | 323.15 .76646 .8644 .8200 .0759 .1393 50 | 323.15 .79464 .9040 .8813 .0375 .0750 51 | 323.15 .81593 .9294 .9263 .0131 .0278 52 | 323.15 .69292 .3526 .3881 .4488 .5148 53 | 323.15 .69536 .3840 .4119 .4142 .4850 54 | 323.15 .69802 .4187 .4382 .3765 .4521 55 | 323.15 .70564 .4590 .4690 .3336 .4136 56 | 323.15 .71431 .5035 .5037 .2872 .3702 57 | 323.15 .72630 .5514 .5425 .2380 .3217 58 | 323.15 .74167 .6004 .5842 .1890 .2696 59 | 323.15 .76520 .6623 .6414 .1284 .1981 60 | 323.15 .79657 .7270 .7089 .0669 .1137 61 | 323.15 .81741 .7635 .7520 .0329 .0597 62 | 323.15 .82789 .7800 .7731 .0179 .0334 63 | 323.15 .83404 .7894 .7856 .0093 .0177 64 | 323.15 .83770 .7954 .7937 .0039 .0076 65 | 323.15 .83918 .7981 .7975 .0015 .0030 66 | 323.15 .83079 .0549 .0999 .5538 .5005 67 | 323.15 .82479 .0615 .1051 .5362 .4744 68 | 323.15 .81748 .0693 .1107 .5160 .4462 69 | 323.15 .80893 .0794 .1172 .4910 .4137 70 | 323.15 .79935 .0913 .1240 .4629 .3798 71 | 323.15 .78598 .1094 .1330 .4225 .3350 72 | 323.15 .76986 .1341 .1434 .3704 .2826 73 | 323.15 .75380 .1631 .1538 .3130 .2305 74 | 323.15 .73738 .2024 .1658 .2404 .1708 75 | 323.15 .72281 .2411 .1708 .1622 .1097 76 | 323.15 .71338 .2870 .1866 .0988 .0669 77 | 323.15 .71057 .3078 .1910 .0664 .0446 78 | 323.15 .70809 .3232 .1942 .0431 .0288 79 | 323.15 .70620 .3353 .1966 .0249 .0166 80 | 323.15 .70494 .3438 .1983 .0123 .0082 81 | 323.15 .70417 .3500 .1995 .0033 .0022 82 | 323.15 .86764 .0118 .0258 .5965 .4973 83 | 323.15 .86037 .0138 .0276 .5792 .4634 84 | 323.15 .85372 .0156 .0290 .5642 .4365 85 | 323.15 .84513 .0178 .0305 .5463 .4070 86 | 323.15 .82969 .0218 .0328 .5162 .3627 87 | 323.15 .81037 .0270 .0351 .4804 .3168 88 | 323.15 .79089 .0325 .0372 .4446 .2769 89 | 323.15 .75748 .0428 .0402 .3834 .2188 90 | 323.15 .72577 .0541 .0427 .3218 .1700 91 | 323.15 .69648 .0666 .0449 .2583 .1271 92 | 323.15 .67152 .0787 .0466 .1999 .0927 93 | 323.15 .65516 .0883 .0478 .1558 .0693 94 | 323.15 .64067 .0976 .0489 .1155 .0496 95 | 323.15 .62955 .1051 .0496 .0826 .0345 96 | 323.15 .61990 .1125 .0503 .0518 .0211 97 | 323.15 .61350 .1177 .0508 .0307 .0123 98 | 323.15 .60960 .1212 .0511 .0164 .0065 99 | 323.15 .88205 .0007 .0028 .7040 .7961 100 | 323.15 .87807 .0029 .0108 .7014 .7897 101 | 323.15 .86881 .0074 .0254 .6962 .7780 102 | 323.15 .85568 .0155 .0475 .6875 .7604 103 | 323.15 .83790 .0281 .0752 .6749 .7383 104 | 323.15 .81664 .0475 .1094 .6567 .7110 105 | 323.15 .79528 .0732 .1460 .6339 .6817 106 | 323.15 .77119 .1111 .1904 .6021 .6463 107 | 323.15 .74589 .1662 .2442 .5581 .6034 108 | 323.15 .72645 .2262 .2952 .5120 .5627 109 | 323.15 .71355 .2845 .3406 .4686 .5264 110 | 323.15 .70576 .3396 .3814 .4288 .4939 111 | 323.15 .70126 .3884 .4168 .3939 .4656 112 | 323.15 .70062 .4306 .4472 .3643 .4413 113 | 323.15 .69889 .4707 .4762 .3364 .4181 114 | 323.15 .69964 .5043 .5007 .3135 .3986 115 | 323.15 .70030 .5197 .5120 .3030 .3896 116 | 323.15 .87343 .0064 .0148 .6052 .5017 117 | 323.15 .84453 .0325 .0618 .5647 .4778 118 | 323.15 .80893 .0794 .1239 .5078 .4462 119 | 323.15 .79157 .1490 .1965 .4393 .4092 120 | 323.15 .76291 .2257 .2658 .3752 .3739 121 | 323.15 .75456 .2838 .3151 .3319 .3488 122 | 323.15 .75086 .3514 .3713 .2857 .3202 123 | 323.15 .75044 .3962 .4084 .2573 .3013 124 | 323.15 .75115 .4301 .4367 .2367 .2868 125 | 323.15 .75286 .4726 .4714 .2081 .2692 126 | 323.15 .75570 .5140 .5081 .1896 .2505 127 | 323.15 .74916 .0074 .0066 .3890 .1983 128 | 323.15 .74686 .0156 .0137 .3809 .1969 129 | 323.15 .74330 .0293 .0254 .3678 .1946 130 | 323.15 .73970 .0475 .0405 .3512 .1916 131 | 323.15 .73654 .0691 .0581 .3326 .1881 132 | 323.15 .73342 .1006 .0832 .3073 .1830 133 | 323.15 .73231 .1542 .1256 .2684 .1746 134 | 323.15 .73585 .2268 .1840 .2218 .1629 135 | 323.15 .74306 .2952 .2418 .1834 .1514 136 | 323.15 .75116 .3511 .2919 .1553 .1414 137 | 323.15 .75906 .3984 .3368 .1337 .1324 138 | 323.15 .76692 .4413 .3797 .1158 .1238 139 | 323.15 .77430 .4792 .4195 .1012 .1159 140 | 323.15 .77706 .5089 .4518 .0906 .1095 141 | 323.15 .78528 .5359 .4819 .0816 .1035 142 | 323.15 .78975 .5592 .5085 .0742 .0981 143 | 323.15 .62140 .0326 .0154 .1320 .0500 144 | 323.15 .64956 .1275 .0652 .1047 .0475 145 | 323.15 .67374 .2031 .1115 .0854 .0452 146 | 323.15 .70292 .2888 .1735 .0659 .0420 147 | 323.15 .72697 .3566 .2316 .0524 .0391 148 | 323.15 .74687 .4120 .2862 .0426 .0363 149 | 323.15 .76263 .4553 .3339 .0357 .0339 150 | 323.15 .77522 .4914 .3770 .0305 .0317 151 | 323.15 .78535 .5215 .4152 .0265 .0297 152 | 323.15 .79319 .5454 .4469 .0237 .0281 153 | 323.15 .80177 .5737 .4858 .0205 .0261 154 | 323.15 .80915 .5991 .5216 .0180 .0243 155 | 323.15 .81591 .6233 .5563 .0159 .0226 156 | -------------------------------------------------------------------------------- /Acet-CHCl3-meth150.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pngts/Nonlinear-parameter-estimation-in-thermodynamic-models/93bd1a062f616e61b0d7214b293b14d48dd16c81/Acet-CHCl3-meth150.xlsx -------------------------------------------------------------------------------- /Acet-CHCl3-meth36.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pngts/Nonlinear-parameter-estimation-in-thermodynamic-models/93bd1a062f616e61b0d7214b293b14d48dd16c81/Acet-CHCl3-meth36.xlsx -------------------------------------------------------------------------------- /AntoineGet.m: -------------------------------------------------------------------------------- 1 | function [names A B C] = AntoineGet(id) 2 | % This function loads AntoineTable and gets the specified rows in vector 'id' 3 | % The function returns vectors with just the desired rows 4 | % This function requires 'AntoineTable.mat' 5 | if(~exist('AntoineTable','var')) 6 | db = load ('AntoineTable.mat'); 7 | AntoineTable = db.AntoineTable; clear db; 8 | end 9 | ncomp = length(id); 10 | for i = 1:ncomp 11 | names{i} = AntoineTable{id(i),1}; 12 | A(i) = AntoineTable{id(i),2}; 13 | B(i) = AntoineTable{id(i),3}; 14 | C(i) = AntoineTable{id(i),4}; 15 | end 16 | end 17 | 18 | % ver 1.01 6/5/12 use struct var for 'load' 19 | -------------------------------------------------------------------------------- /AntoineTable.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pngts/Nonlinear-parameter-estimation-in-thermodynamic-models/93bd1a062f616e61b0d7214b293b14d48dd16c81/AntoineTable.mat -------------------------------------------------------------------------------- /AntoineTableBrowse.m: -------------------------------------------------------------------------------- 1 | %This script is to browse the Antoine table to see the 2 | %index values and temperature limits. 3 | if(~exist('AntoineTable','var')) 4 | db = load('AntoineTable.mat'); 5 | AntoineTable = db.AntoineTable; clear db; 6 | end 7 | fprintf('%d %s %s %s %s\n',1, AntoineTable{1,1}, AntoineTable{1,5}, AntoineTable{1,6}, AntoineTable{1,7}) 8 | for i=2:length(AntoineTable(:,1)) 9 | %disp([i AntoineTable(i,1) AntoineTable(i,5) AntoineTable(i,6)]) 10 | fprintf('%d %s %.1f %.1f %d\n',i, AntoineTable{i,1}, AntoineTable{i,5}, AntoineTable{i,6}, AntoineTable{i,7}) 11 | end 12 | 13 | % ver 1.01 6/5/12 improve printing, use struct var for 'load' -------------------------------------------------------------------------------- /BB_ALL.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pngts/Nonlinear-parameter-estimation-in-thermodynamic-models/93bd1a062f616e61b0d7214b293b14d48dd16c81/BB_ALL.mat -------------------------------------------------------------------------------- /CHCL3-METH.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pngts/Nonlinear-parameter-estimation-in-thermodynamic-models/93bd1a062f616e61b0d7214b293b14d48dd16c81/CHCL3-METH.xlsx -------------------------------------------------------------------------------- /FIT_FUNCTION_FORUNIQUAC_FAST.m: -------------------------------------------------------------------------------- 1 | function [fitness]=FIT_FUNCTION_FORUNIQUAC_FAST(du,components) 2 | global TK R gamma_exp X r q q1 gamma_cal 3 | 4 | switch components 5 | case 4 6 | du12=du(1); du13=du(2); du14=du(3); du21=du(4);du23=du(5);du24=du(6);du31=du(7);du32=du(8);du34=du(9);du41=du(10);du42=du(11);du43=du(12); 7 | error=0;error1=0; 8 | for i=1:length(X) 9 | tau=[1 exp(-du12./TK(i)/R) exp(-du13./TK(i)/R) exp(-du14./TK(i)/R);exp(-du21./TK(i)/R) 1 exp(-du23./TK(i)/R) exp(-du24./TK(i)/R);exp(-du31./TK(i)/R) exp(-du32./TK(i)/R) 1 exp(-du34./TK(i)/R);exp(-du41./TK(i)/R) exp(-du42./TK(i)/R) exp(-du43./TK(i)/R) 1] ; 10 | x=[X(i,1) X(i,2) X(i,3) X(i,4)]; 11 | gamma_cal(i,:)=uniquac_fast(x, r, q, q1,tau,i); 12 | error=error1 +((gamma_cal(i,1)-gamma_exp(i,1))/gamma_exp(i,1))^2 +((gamma_cal(i,2)-gamma_exp(i,2))/gamma_exp(i,2))^2 +((gamma_cal(i,3)-gamma_exp(i,3))/gamma_exp(i,3))^2+((gamma_cal(i,4)-gamma_exp(i,4))/gamma_exp(i,4))^2; 13 | error1=error; 14 | end 15 | case 3 16 | du12=du(1); du13=du(2); du21=du(3);du23=du(4);du31=du(5);du32=du(6); 17 | error=0;error1=0; 18 | for i=1:length(X) 19 | tau=[1 exp(-du12./TK(i)/R) exp(-du13./TK(i)/R);exp(-du21./TK(i)/R) 1 exp(-du23./TK(i)/R);exp(-du31./TK(i)/R) exp(-du32./TK(i)/R) 1] ; 20 | x=[X(i,1) X(i,2) X(i,3)]; 21 | gamma_cal(i,:)=uniquac_fast(x, r, q, q1,tau); 22 | error=error1 +((gamma_cal(i,1)-gamma_exp(i,1))/gamma_exp(i,1))^2 +((gamma_cal(i,2)-gamma_exp(i,2))/gamma_exp(i,2))^2 +((gamma_cal(i,3)-gamma_exp(i,3))/gamma_exp(i,3))^2; 23 | error1=error; 24 | end 25 | case 2 26 | du12=du(1); du21=du(2); 27 | error=0;error1=0; 28 | for i=1:length(X) 29 | tau=[1 exp(-du12./TK(i)/R);exp(-du21./TK(i)/R) 1 ] ; 30 | x=[X(i,1) X(i,2)]; 31 | gamma_cal(i,:)=uniquac_fast(x, r, q, q1,tau); 32 | error=error1 +((gamma_cal(i,1)-gamma_exp(i,1))/gamma_exp(i,1))^2 +((gamma_cal(i,2)-gamma_exp(i,2))/gamma_exp(i,2))^2; 33 | error1=error; 34 | end 35 | 36 | end 37 | fitness=1/error; -------------------------------------------------------------------------------- /FIT_function_flex.m: -------------------------------------------------------------------------------- 1 | function [fitness]=FIT_function_flex(du,components) 2 | global TK R gamma_exp X r q q1 gamma_cal 3 | 4 | switch components 5 | case 3 6 | du12=du(1); du13=du(2); du21=du(3);du23=du(4);du31=du(5);du32=du(6); 7 | tau=[1 exp(-du12./TK./R) exp(-du13./TK./R);exp(-du21./TK./R) 1 exp(-du23./TK./R);exp(-du31./TK./R) exp(-du32./TK./R) 1] ; 8 | error=0;error1=0; 9 | for i=1:length(X) 10 | x=[X(i,1) X(i,2) X(i,3)]; 11 | gamma_cal(i,:)=uniquac(x, r, q, q1,tau); 12 | error=error1 +((gamma_cal(i,1)-gamma_exp(i,1))/gamma_exp(i,1))^2 +((gamma_cal(i,2)-gamma_exp(i,2))/gamma_exp(i,2))^2 +((gamma_cal(i,3)-gamma_exp(i,3))/gamma_exp(i,3))^2; 13 | % error=error1 +abs(gamma_cal(i,1)-gamma_exp(i,1))+abs(gamma_cal(i,2)-gamma_exp(i,2))+abs(gamma_cal(i,3)-gamma_exp(i,3)) ; 14 | error1=error; 15 | end 16 | case 2 17 | du12=du(1); du21=du(2); 18 | tau=[1 exp(-du12./TK./R);exp(-du21./TK./R) 1 ] ; 19 | error=0;error1=0; 20 | for i=1:length(X) 21 | x=[X(i,1) X(i,2)]; 22 | gamma_cal(i,:)=uniquac(x, r, q, q1,tau); 23 | error=error1 +((gamma_cal(i,1)-gamma_exp(i,1))/gamma_exp(i,1))^2 +((gamma_cal(i,2)-gamma_exp(i,2))/gamma_exp(i,2))^2; 24 | error1=error; 25 | end 26 | 27 | end 28 | fitness=1/error; -------------------------------------------------------------------------------- /FIT_function_flexTP.m: -------------------------------------------------------------------------------- 1 | function [fitness]=FIT_function_flexTP(du,components) 2 | global TK R gamma_exp X r q q1 gamma_cal 3 | 4 | switch components 5 | case 4 6 | du12=du(1); du13=du(2); du14=du(3); du21=du(4);du23=du(5);du24=du(6);du31=du(7);du32=du(8);du34=du(9);du41=du(10);du42=du(11);du43=du(12); 7 | error=0;error1=0; 8 | for i=1:length(X) 9 | tau=[1 exp(-du12./TK(i)/R) exp(-du13./TK(i)/R) exp(-du14./TK(i)/R);exp(-du21./TK(i)/R) 1 exp(-du23./TK(i)/R) exp(-du24./TK(i)/R);exp(-du31./TK(i)/R) exp(-du32./TK(i)/R) 1 exp(-du34./TK(i)/R);exp(-du41./TK(i)/R) exp(-du42./TK(i)/R) exp(-du43./TK(i)/R) 1] ; 10 | x=[X(i,1) X(i,2) X(i,3) X(i,4)]; 11 | gamma_cal(i,:)=uniquac(x, r, q, q1,tau); 12 | error=error1 +((gamma_cal(i,1)-gamma_exp(i,1))/gamma_exp(i,1))^2 +((gamma_cal(i,2)-gamma_exp(i,2))/gamma_exp(i,2))^2 +((gamma_cal(i,3)-gamma_exp(i,3))/gamma_exp(i,3))^2+((gamma_cal(i,4)-gamma_exp(i,4))/gamma_exp(i,4))^2; 13 | error1=error; 14 | end 15 | case 3 16 | du12=du(1); du13=du(2); du21=du(3);du23=du(4);du31=du(5);du32=du(6); 17 | error=0;error1=0; 18 | for i=1:length(X) 19 | tau=[1 exp(-du12./TK(i)/R) exp(-du13./TK(i)/R);exp(-du21./TK(i)/R) 1 exp(-du23./TK(i)/R);exp(-du31./TK(i)/R) exp(-du32./TK(i)/R) 1] ; 20 | x=[X(i,1) X(i,2) X(i,3)]; 21 | gamma_cal(i,:)=uniquac(x, r, q, q1,tau); 22 | error=error1 +((gamma_cal(i,1)-gamma_exp(i,1))/gamma_exp(i,1))^2 +((gamma_cal(i,2)-gamma_exp(i,2))/gamma_exp(i,2))^2 +((gamma_cal(i,3)-gamma_exp(i,3))/gamma_exp(i,3))^2; 23 | error1=error; 24 | end 25 | case 2 26 | du12=du(1); du21=du(2); 27 | error=0;error1=0; 28 | for i=1:length(X) 29 | tau=[1 exp(-du12./TK(i)/R);exp(-du21./TK(i)/R) 1 ] ; 30 | x=[X(i,1) X(i,2)]; 31 | gamma_cal(i,:)=uniquac(x, r, q, q1,tau); 32 | error=error1 +((gamma_cal(i,1)-gamma_exp(i,1))/gamma_exp(i,1))^2 +((gamma_cal(i,2)-gamma_exp(i,2))/gamma_exp(i,2))^2; 33 | error1=error; 34 | end 35 | 36 | end 37 | fitness=1/error; -------------------------------------------------------------------------------- /FIT_function_flexTP_meshgrid.m: -------------------------------------------------------------------------------- 1 | function [fitness]=FIT_function_flexTP_meshgrid(du1,du2,components) 2 | global TK R gamma_exp X r q q1 gamma_cal 3 | 4 | switch components 5 | case 4 6 | du12=du(1); du13=du(2); du14=du(3); du21=du(4);du23=du(5);du24=du(6);du31=du(7);du32=du(8);du34=du(9);du41=du(10);du42=du(11);du43=du(12); 7 | error=0;error1=0; 8 | for i=1:length(X) 9 | tau=[1 exp(-du12./TK(i)/R) exp(-du13./TK(i)/R) exp(-du14./TK(i)/R);exp(-du21./TK(i)/R) 1 exp(-du23./TK(i)/R) exp(-du24./TK(i)/R);exp(-du31./TK(i)/R) exp(-du32./TK(i)/R) 1 exp(-du34./TK(i)/R);exp(-du41./TK(i)/R) exp(-du42./TK(i)/R) exp(-du43./TK(i)/R) 1] ; 10 | x=[X(i,1) X(i,2) X(i,3) X(i,4)]; 11 | gamma_cal(i,:)=uniquac(x, r, q, q1,tau); 12 | error=error1 +((gamma_cal(i,1)-gamma_exp(i,1))/gamma_exp(i,1))^2 +((gamma_cal(i,2)-gamma_exp(i,2))/gamma_exp(i,2))^2 +((gamma_cal(i,3)-gamma_exp(i,3))/gamma_exp(i,3))^2+((gamma_cal(i,4)-gamma_exp(i,4))/gamma_exp(i,4))^2; 13 | error1=error; 14 | end 15 | case 3 16 | du12=du(1); du13=du(2); du21=du(3);du23=du(4);du31=du(5);du32=du(6); 17 | error=0;error1=0; 18 | for i=1:length(X) 19 | tau=[1 exp(-du12./TK(i)/R) exp(-du13./TK(i)/R);exp(-du21./TK(i)/R) 1 exp(-du23./TK(i)/R);exp(-du31./TK(i)/R) exp(-du32./TK(i)/R) 1] ; 20 | x=[X(i,1) X(i,2) X(i,3)]; 21 | gamma_cal(i,:)=uniquac(x, r, q, q1,tau); 22 | error=error1 +((gamma_cal(i,1)-gamma_exp(i,1))/gamma_exp(i,1))^2 +((gamma_cal(i,2)-gamma_exp(i,2))/gamma_exp(i,2))^2 +((gamma_cal(i,3)-gamma_exp(i,3))/gamma_exp(i,3))^2; 23 | error1=error; 24 | end 25 | case 2 26 | du12=du1; du21=du2; 27 | error=0;error1=0; 28 | for i=1:length(X) 29 | tau=[1 exp(-du12./TK(i)/R);exp(-du21./TK(i)/R) 1 ] ; 30 | x=[X(i,1) X(i,2)]; 31 | gamma_cal(i,:)=uniquac(x, r, q, q1,tau); 32 | error=error1 +((gamma_cal(i,1)-gamma_exp(i,1))/gamma_exp(i,1))^2 +((gamma_cal(i,2)-gamma_exp(i,2))/gamma_exp(i,2))^2; 33 | error1=error; 34 | end 35 | 36 | end 37 | fitness=1/error; -------------------------------------------------------------------------------- /Fit_function.m: -------------------------------------------------------------------------------- 1 | function [fitness]=Fit_function(du12,du21) 2 | global TK R gamma_exp X r q q1 gamma_cal 3 | %% prota ipologizonte to gammaCalc apo tin uniquac 4 | %du12=-362.3272; du21=139.1319; 5 | %du12=-359.6; du21=575.49; 6 | %du12=-585.41; du21=1065.404; 7 | %du12=493.2754; du21=-131.5598; 8 | 9 | tau=[1 exp(-du12./TK./R);exp(-du21./TK./R) 1 ] ; 10 | error=0;error1=0; 11 | for i=1:length(X) 12 | x=[X(i,1) X(i,2)]; 13 | gamma_cal(i,:)=uniquac(x, r, q, q1,tau); 14 | error=error1 +((gamma_cal(i,1)-gamma_exp(i,1))/gamma_exp(i,1))^2 +((gamma_cal(i,2)-gamma_exp(i,2))/gamma_exp(i,2))^2; 15 | error1=error; 16 | end 17 | fitness=1/error; -------------------------------------------------------------------------------- /Fit_functionT.m: -------------------------------------------------------------------------------- 1 | function [fitness]=Fit_functionT(du12,du21) 2 | global TK R gamma_exp X r q q1 gamma_cal 3 | %% prota ipologizonte to gammaCalc apo tin uniquac 4 | %du12=-362.3272; du21=139.1319; 5 | %du12=-359.6; du21=575.49; 6 | %du12=-585.41; du21=1065.404; 7 | %du12=231*R; du21=-10.61*R; 8 | 9 | error=0;error1=0; 10 | for i=1:length(X) 11 | tau=[1 exp(-du12./TK(i)/R);exp(-du21./TK(i)/R) 1 ] ; 12 | x=[X(i,1) X(i,2)]; 13 | gamma_cal(i,:)=uniquac(x, r, q, q1,tau); 14 | error=error1 +((gamma_cal(i,1)-gamma_exp(i,1))/gamma_exp(i,1))^2 +((gamma_cal(i,2)-gamma_exp(i,2))/gamma_exp(i,2))^2; 15 | error1=error; 16 | end 17 | fitness=1/error; -------------------------------------------------------------------------------- /Fit_function_TERN.m: -------------------------------------------------------------------------------- 1 | function [fitness]=Fit_function_TERN(du12,du13,du21,du23,du31,du32) 2 | global TK R gamma_exp X r q q1 gamma_cal 3 | %% prota ipologizonte to gammaCalc apo tin uniquac 4 | %du12=-130.2535*1.9872;du13=-81.56071*1.9872;du21=-34.51268*1.9872;du23=-873.6794*1.9872;du31=179.9613*1.9872;du32=304.4958*1.9872; 5 | %du12=-315.49*R;du13=378.93*R;du21=-228.24*R;du23=-52.15*R;du31=691.51*R;du32=-142.79*R; 6 | % du12=892.176910603683;du13=493.755343490955;du21=-426.625512950253;du23=-425.872500366702;du31=34.5200694478557;du32=615.206598583084; 7 | 8 | tau=[1 exp(-du12./TK./R) exp(-du13./TK./R);exp(-du21./TK./R) 1 exp(-du23./TK./R);exp(-du31./TK./R) exp(-du32./TK./R) 1] ; 9 | error=0;error1=0; 10 | for i=1:length(X) 11 | x=[X(i,1) X(i,2) X(i,3)]; 12 | gamma_cal(i,:)=uniquac(x, r, q, q1,tau); 13 | error=error1 +((gamma_cal(i,1)-gamma_exp(i,1))/gamma_exp(i,1))^2 +((gamma_cal(i,2)-gamma_exp(i,2))/gamma_exp(i,2))^2 +((gamma_cal(i,3)-gamma_exp(i,3))/gamma_exp(i,3))^2; 14 | % error=error1 +abs(gamma_cal(i,1)-gamma_exp(i,1))+abs(gamma_cal(i,2)-gamma_exp(i,2))+abs(gamma_cal(i,3)-gamma_exp(i,3)) ; 15 | error1=error; 16 | end 17 | fitness=1/error; -------------------------------------------------------------------------------- /Fit_function_TERN2.m: -------------------------------------------------------------------------------- 1 | function [fitness]=Fit_function_TERN2(du12,du13,du21,du23,du31,du32) 2 | global TK R gamma_exp X r q q1 gamma_cal 3 | %% prota ipologizonte to gammaCalc apo tin uniquac 4 | %du12=-130.2535*1.9872;du13=-81.56071*1.9872;du21=-34.51268*1.9872;du23=-873.6794*1.9872;du31=179.9613*1.9872;du32=304.4958*1.9872; 5 | %du12=-315.49*R;du13=378.93*R;du21=-228.24*R;du23=-52.15*R;du31=691.51*R;du32=-142.79*R; 6 | % du12=892.176910603683;du13=493.755343490955;du21=-426.625512950253;du23=-425.872500366702;du31=34.5200694478557;du32=615.206598583084; 7 | 8 | tau=[1 exp(-du12./TK./R) exp(-du13./TK./R);exp(-du21./TK./R) 1 exp(-du23./TK./R);exp(-du31./TK./R) exp(-du32./TK./R) 1] ; 9 | error=0;error1=0; 10 | for i=1:length(X) 11 | x=[X(i,1) X(i,2) X(i,3)]; 12 | gamma_cal(i,:)=uniquac(x, r, q, q1,tau); 13 | error=error1 +((gamma_cal(i,1)-gamma_exp(i,1))/gamma_exp(i,1))^2 +((gamma_cal(i,2)-gamma_exp(i,2))/gamma_exp(i,2))^2 +((gamma_cal(i,3)-gamma_exp(i,3))/gamma_exp(i,3))^2; 14 | % error=error1 +abs(gamma_cal(i,1)-gamma_exp(i,1))+abs(gamma_cal(i,2)-gamma_exp(i,2))+abs(gamma_cal(i,3)-gamma_exp(i,3)) ; 15 | error1=error; 16 | end 17 | fitness=1/error; -------------------------------------------------------------------------------- /IMPORT_QUERN_WITH_GAMMA.m: -------------------------------------------------------------------------------- 1 | %% Import data from spreadsheet 2 | % Script for importing data from the following spreadsheet: 3 | % 4 | % Workbook: E:\THESIS\piramatika voutsas\TERNARY\quaternary1_GAMMA.xlsx 5 | % Worksheet: SHEET1 6 | % 7 | % To extend the code for use with different selected data or a different 8 | % spreadsheet, generate a function instead of a script. 9 | 10 | % Auto-generated by MATLAB on 2018/03/14 12:31:56 11 | 12 | %% Import the data 13 | [~, ~, raw] = xlsread('E:\THESIS\piramatika voutsas\quaternary\quaternary1_GAMMA.xlsx','SHEET1','A4:L37'); 14 | 15 | %% Create output variable 16 | data = reshape([raw{:}],size(raw)); 17 | 18 | %% Allocate imported array to column variable names 19 | TK = data(:,1); 20 | PmmHg = data(:,2); 21 | X1 = data(:,3); 22 | X2 = data(:,4); 23 | X3 = data(:,5); 24 | Y1 = data(:,6); 25 | Y2 = data(:,7); 26 | Y3 = data(:,8); 27 | gamma_exp1 = data(:,9); 28 | gamma_exp2 = data(:,10); 29 | gamma_exp3 = data(:,11); 30 | gamma_exp4 = data(:,12); 31 | 32 | %% Clear temporary variables 33 | clearvars data raw; -------------------------------------------------------------------------------- /LMFsolve.m: -------------------------------------------------------------------------------- 1 | function [xf, S, cnt] = LMFsolve(varargin) 2 | % LMFSOLVE Solve a Set of Nonlinear Equations in Least-Squares Sense. 3 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4 | % A solution is obtained by a shortened Fletcher version of the 5 | % Levenberg-Maquardt algoritm for minimization of a sum of squares 6 | % of equation residuals. [du] = LMFsolve(ff,du0,'FunTol',0,'MaxIter',500,'XTol',0.001,'ScaleD',value) 7 | % 8 | % [Xf, Ssq, CNT] = LMFsolve(FUN,Xo,Options) 9 | % FUN is a function handle or a function M-file name that evaluates 10 | % m-vector of equation residuals, 11 | % Xo is n-vector of initial guesses of solution, 12 | % Options is an optional set of Name/Value pairs of control parameters 13 | % of the algorithm. It may be also preset by calling: 14 | % Options = LMFsolve('default'), or by a set of Name/Value pairs: 15 | % Options = LMFsolve('Name',Value, ... ), or updating the Options 16 | % set by calling 17 | % Options = LMFsolve(Options,'Name',Value, ...). 18 | % 19 | % Name Values {default} Description 20 | % 'Display' integer Display iteration information 21 | % {0} no display 22 | % k display initial and every k-th iteration; 23 | % 'FunTol' {1e-7} norm(FUN(x),1) stopping tolerance; 24 | % 'XTol' {1e-7} norm(x-xold,1) stopping tolerance; 25 | % 'MaxIter' {100} Maximum number of iterations; 26 | % 'ScaleD' Scale control: 27 | % value D = eye(m)*value; 28 | % vector D = diag(vector); 29 | % {[]} D(k,k) = JJ(k,k) for JJ(k,k)>0, or 30 | % = 1 otherwise, 31 | % where JJ = J.'*J 32 | % Not defined fields of the Options structure are filled by default values. 33 | % 34 | % Output Arguments: 35 | % Xf final solution approximation 36 | % Ssq sum of squares of residuals 37 | % Cnt >0 count of iterations 38 | % -MaxIter, did not converge in MaxIter iterations 39 | 40 | % Example: Rosenbrock valey inside circle with unit diameter 41 | % R = @(x) sqrt(x'*x)-.5; % A distance from the radius r=0.5 42 | % ros= @(x) [ 10*(x(2)-x(1)^2); 1-x(1); (R(x)>0)*R(x)*1000]; 43 | % [x,ssq,cnt]=LMFsolve(ros,[-1.2,1],'Display',1,'MaxIter',50) 44 | % returns x = [0.4556; 0.2059], ssq = 0.2966, cnt = 18. 45 | % 46 | % Note: Users with old MATLAB versions (<7), which have no anonymous 47 | % functions implemented, should call LMFsolve with named function for 48 | % residuals. For above example it is 49 | % [x,ssq,cnt]=LMFsolve('rosen',[-1.2,1]); 50 | % where the function rosen.m is of the form 51 | % function r = rosen(x) 52 | %% Rosenbrock valey with a constraint 53 | % R = sqrt(x(1)^2+x(2)^2)-.5; 54 | %% Residuals: 55 | % r = [ 10*(x(2)-x(1)^2) % first part 56 | % 1-x(1) % second part 57 | % (R>0)*R*1000. % penalty 58 | % ]; 59 | 60 | % Reference: 61 | % Fletcher, R., (1971): A Modified Marquardt Subroutine for Nonlinear Least 62 | % Squares. Rpt. AERE-R 6799, Harwell 63 | 64 | % Miroslav Balda, 65 | % balda AT cdm DOT cas DOT cz 66 | % 2007-07-02 v 1.0 67 | % 2008-12-22 v 1.1 * Changed name of the function in LMFsolv 68 | % * Removed part with wrong code for use of analytical 69 | % form for assembling of Jacobian matrix 70 | % 2009-01-08 v 1.2 * Changed subfunction printit.m for better one, and 71 | % modified its calling from inside LMFsolve. 72 | % * Repaired a bug, which caused an inclination to 73 | % istability, in charge of slower convergence. 74 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 75 | 76 | % OPTIONS 77 | %%%%%%% 78 | % Default Options 79 | if nargin==1 && strcmpi('default',varargin(1)) 80 | xf.Display = 0; % no print of iterations 81 | xf.MaxIter = 100; % maximum number of iterations allowed 82 | xf.ScaleD = []; % automatic scaling by D = diag(diag(J'*J)) 83 | xf.FunTol = 1e-7; % tolerace for final function value 84 | xf.XTol = 1e-4; % tolerance on difference of x-solutions 85 | return 86 | 87 | % Updating Options 88 | elseif isstruct(varargin{1}) % Options=LMFsolve(Options,'Name','Value',...) 89 | if ~isfield(varargin{1},'Display') 90 | error('Options Structure not correct for LMFsolve.') 91 | end 92 | xf=varargin{1}; % Options 93 | for i=2:2:nargin-1 94 | name=varargin{i}; % Option to be updated 95 | if ~ischar(name) 96 | error('Parameter Names Must be Strings.') 97 | end 98 | name=lower(name(isletter(name))); 99 | value=varargin{i+1}; % value of the option 100 | if strncmp(name,'d',1), xf.Display = value; 101 | elseif strncmp(name,'f',1), xf.FunTol = value(1); 102 | elseif strncmp(name,'x',1), xf.XTol = value(1); 103 | elseif strncmp(name,'m',1), xf.MaxIter = value(1); 104 | elseif strncmp(name,'s',1), xf.ScaleD = value; 105 | else disp(['Unknown Parameter Name --> ' name]) 106 | end 107 | end 108 | return 109 | 110 | % Pairs of Options 111 | elseif ischar(varargin{1}) % check for Options=LMFSOLVE('Name',Value,...) 112 | Pnames=char('display','funtol','xtol','maxiter','scaled'); 113 | if strncmpi(varargin{1},Pnames,length(varargin{1})) 114 | xf=LMFsolve('default'); % get default values 115 | xf=LMFsolve(xf,varargin{:}); 116 | return 117 | end 118 | end 119 | 120 | % LMFSOLVE(FUN,Xo,Options) 121 | %%%%%%%%%%%%%%%%%%%%%%%% 122 | 123 | FUN=varargin{1}; % function handle 124 | if ~(isvarname(FUN) || isa(FUN,'function_handle')) 125 | error('FUN Must be a Function Handle or M-file Name.') 126 | end 127 | 128 | xc=varargin{2}; % Xo 129 | 130 | if nargin>2 % OPTIONS 131 | if isstruct(varargin{3}) 132 | options=varargin{3}; 133 | else 134 | if ~exist('options','var') 135 | options = LMFsolve('default'); 136 | end 137 | for i=3:2:size(varargin,2)-1 138 | options=LMFsolve(options, varargin{i},varargin{i+1}); 139 | end 140 | end 141 | else 142 | if ~exist('options','var') 143 | options = LMFsolve('default'); 144 | end 145 | end 146 | 147 | x = xc(:); 148 | lx = length(x); 149 | 150 | r = feval(FUN,x); % Residuals at starting point 151 | %~~~~~~~~~~~~~~~~~ 152 | S = r'*r; 153 | epsx = options.XTol(:); 154 | epsf = options.FunTol(:); 155 | if length(epsx)1 170 | D = diag(sqrt(abs(D(1:lx)))); % vector of individual scaling 171 | else 172 | D = sqrt(abs(D))*eye(lx); % scalar of unique scaling 173 | end 174 | end 175 | 176 | Rlo = 0.25; 177 | Rhi = 0.75; 178 | l=1; lc=.75; is=0; 179 | cnt = 0; 180 | ipr = options.Display; 181 | printit(ipr,-1); % Table header 182 | d = options.XTol; % vector for the first cycle 183 | maxit = options.MaxIter; % maximum permitted number of iterations 184 | 185 | while cnt= epsx) && ... %%%%%%%%%%%%%%%%%%%% 187 | any(abs(r) >= epsf) 188 | d = (A+l*D)\v; % negative solution increment 189 | xd = x-d; 190 | rd = feval(FUN,xd); 191 | % ~~~~~~~~~~~~~~~~~~~ 192 | nfJ = nfJ+1; 193 | Sd = rd.'*rd; 194 | dS = d.'*(2*v-A*d); % predicted reduction 195 | 196 | R = (S-Sd)/dS; 197 | if R>Rhi % halve lambda if R too high 198 | l = l/2; 199 | if l10 205 | nu = 10; 206 | end 207 | if l==0 208 | lc = 1/max(abs(diag(inv(A)))); 209 | l = lc; 210 | nu = nu/2; 211 | end 212 | l = nu*l; 213 | end 214 | 215 | cnt = cnt+1; 216 | if ipr~=0 && (rem(cnt,ipr)==0 || cnt==1) % print iteration? 217 | printit(ipr,cnt,nfJ,S,x,d,l,lc) 218 | end 219 | 220 | if Sd 0 print every (ipr)th iteration 264 | % cnt = -1 print out the header 265 | % 0 print out second row of results 266 | % >0 print out first row of results 267 | if ipr~=0 268 | if cnt<0 % table header 269 | disp('') 270 | disp(char('*'*ones(1,75))) 271 | fprintf(' itr nfJ SUM(r^2) x dx'); 272 | if ipr>0 273 | fprintf(' l lc'); 274 | end 275 | fprintf('\n'); 276 | disp(char('*'*ones(1,75))) 277 | disp('') 278 | else % iteration output 279 | if rem(cnt,ipr)==0 280 | f='%12.4e '; 281 | if ipr>0 282 | fprintf(['%4.0f %4.0f ' f f f f f '\n'],... 283 | cnt,res,SS, x(1),dx(1),l,lc); 284 | else 285 | fprintf(['%4.0f %4.0f ' f f f '\n'],... 286 | cnt,res,SS, x(1),dx(1)); 287 | end 288 | for k=2:length(x) 289 | fprintf([blanks(23) f f '\n'],x(k),dx(k)); 290 | end 291 | end 292 | end 293 | end 294 | -------------------------------------------------------------------------------- /LMFsolveOLD.m: -------------------------------------------------------------------------------- 1 | function [xf, S, cnt] = LMFsolveOLD(varargin) 2 | % Solve a Set of Overdetermined Nonlinear Equations in Least-Squares Sense. 3 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4 | % A solution is obtained by a Fletcher version of the Levenberg-Maquardt 5 | % algoritm for minimization of a sum of squares of equation residuals. 6 | % 7 | % [Xf, Ssq, CNT] = LMFsolveOLD(FUN,Xo,Options) 8 | % FUN is a function handle or a function M-file name that evaluates 9 | % m-vector of equation residuals, 10 | % Xo is n-vector of initial guesses of solution, 11 | % Options is an optional set of Name/Value pairs of control parameters 12 | % of the algorithm. It may be also preset by calling: 13 | % Options = LMFsolveOLD('default'), or by a set of Name/Value pairs: 14 | % Options = LMFsolveOLD('Name',Value, ... ), or updating the Options 15 | % set by calling 16 | % Options = LMFsolveOLD(Options,'Name',Value, ...). 17 | % 18 | % Name Values {default} Description 19 | % 'Display' integer Display iteration information 20 | % {0} no display 21 | % k display initial and every k-th iteration; 22 | % 'Jacobian' handle Jacobian matrix function handle; {@finjac} 23 | % 'FunTol' {1e-7} norm(FUN(x),1) stopping tolerance; 24 | % 'XTol' {1e-7} norm(x-xold,1) stopping tolerance; 25 | % 'MaxIter' {100} Maximum number of iterations; 26 | % 'ScaleD' Scale control: 27 | % value D = eye(m)*value; 28 | % vector D = diag(vector); 29 | % {[]} D(k,k) = JJ(k,k) for JJ(k,k)>0, or 30 | % = 1 otherwise, 31 | % where JJ = J.'*J 32 | % Not defined fields of the Options structure are filled by default values. 33 | % 34 | % Output Arguments: 35 | % Xf final solution approximation 36 | % Ssq sum of squares of residuals 37 | % Cnt >0 count of iterations 38 | % -MaxIter, did not converge in MaxIter iterations 39 | 40 | % Example: 41 | % The general Rosenbrock's function has the form 42 | % f(x) = 100(x(1)-x(2)^2)^2 + (1-x(1))^2 43 | % Optimum solution gives f(x)=0 for x(1)=x(2)=1. Function f(x) can be 44 | % expressed in the form 45 | % f(x) = f1(x)^2 =f2(x)^2, 46 | % where f1(x) = 10(x(1)-x(2)^2) and f2(x) = 1-x(1). 47 | % Values of the functions f1(x) and f2(x) can be used as residuals. 48 | % LMFsolveOLD finds the solution of this problem in 5 iterations. The more 49 | % complicated problem sounds: 50 | % Find the least squares solution of the Rosenbrock valey inside a circle 51 | % of the unit diameter centered at the origin. It is necessary to build 52 | % third function, which is zero inside the circle and increasing outside it. 53 | % This property has, say, the next function: 54 | % f3(x) = sqrt(x(1)^2 + x(2)^2) - r, where r is a radius of the circle. 55 | % Its implementation using anonymous functions has the form 56 | % R = @(x) sqrt(x'*x)-.5; % A distance from the radius r=0.5 57 | % ros= @(x) [10*(x(2)-x(1)^2); 1-x(1); (R(x)>0)*R(x)*1000]; 58 | % [x,ssq,cnt]=LMFsolveOLD(ros,[-1.2,1],'Display',1,'MaxIter',50) 59 | % Solution: x = [0.4556; 0.2059], |x| = 0.5000 60 | % sum of squares: ssq = 0.2966, 61 | % number of iterations: cnt = 18. 62 | % 63 | % Note: 64 | % Users with older MATLAB versions, which have no anonymous functions 65 | % implemented, have to call LMFsolveOLD with named function for residuals. 66 | % For above example it is 67 | % 68 | % [x,ssq,cnt]=LMFsolveOLD('rosen',[-1.2,1]); 69 | % 70 | % where the function rosen.m is of the form 71 | % 72 | % function r = rosen(x) 73 | %% Rosenbrock valey with a constraint 74 | % R = sqrt(x(1)^2+x(2)^2)-.5; 75 | %% Residuals: 76 | % r = [ 10*(x(2)-x(1)^2) % first part 77 | % 1-x(1) % second part 78 | % (R>0)*R*1000. % penalty 79 | % ]; 80 | 81 | % Reference: 82 | % Fletcher, R., (1971): A Modified Marquardt Subroutine for Nonlinear Least 83 | % Squares. Rpt. AERE-R 6799, Harwell 84 | 85 | % M. Balda, 86 | % Institute of Thermomechanics, 87 | % Academy of Sciences of The Czech Republic, 88 | % balda AT cdm DOT cas DOT cz 89 | % 2007-07-02 90 | % 2007-10-08 formal changes, improved description 91 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 92 | 93 | % OPTIONS 94 | %%%%%%% 95 | % Default Options 96 | if nargin==1 && strcmpi('default',varargin(1)) 97 | xf.Display = 0; % no print of iterations 98 | xf.Jacobian = @finjac; % finite difference Jacobian approximation 99 | xf.MaxIter = 100; % maximum number of iterations allowed 100 | xf.ScaleD = []; % automatic scaling by D = diag(diag(J'*J)) 101 | xf.FunTol = 1e-7; % tolerace for final function value 102 | xf.XTol = 1e-4; % tolerance on difference of x-solutions 103 | return 104 | 105 | % Updating Options 106 | elseif isstruct(varargin{1}) % Options=LMFsolveOLD(Options,'Name','Value',...) 107 | if ~isfield(varargin{1},'Jacobian') 108 | error('Options Structure not Correct for LMFsolveOLD.') 109 | end 110 | xf=varargin{1}; % Options 111 | for i=2:2:nargin-1 112 | name=varargin{i}; % option to be updated 113 | if ~ischar(name) 114 | error('Parameter Names Must be Strings.') 115 | end 116 | name=lower(name(isletter(name))); 117 | value=varargin{i+1}; % value of the option 118 | if strncmp(name,'d',1), xf.Display = value; 119 | elseif strncmp(name,'f',1), xf.FunTol = value(1); 120 | elseif strncmp(name,'x',1), xf.XTol = value(1); 121 | elseif strncmp(name,'j',1), xf.Jacobian = value; 122 | elseif strncmp(name,'m',1), xf.MaxIter = value(1); 123 | elseif strncmp(name,'s',1), xf.ScaleD = value; 124 | else disp(['Unknown Parameter Name --> ' name]) 125 | end 126 | end 127 | return 128 | 129 | % Pairs of Options 130 | elseif ischar(varargin{1}) % check for Options=LMFsolveOLD('Name',Value,...) 131 | Pnames=char('display','funtol','xtol','jacobian','maxiter','scaled'); 132 | if strncmpi(varargin{1},Pnames,length(varargin{1})) 133 | xf=LMFsolveOLD('default'); % get default values 134 | xf=LMFsolveOLD(xf,varargin{:}); 135 | return 136 | end 137 | end 138 | 139 | % LMFSOLVEOLD(FUN,Xo,Options) 140 | %%%%%%%%%%%%%%%%%%%%%%%%%%% 141 | 142 | FUN=varargin{1}; % function handle 143 | if ~(isvarname(FUN) || isa(FUN,'function_handle')) 144 | error('FUN Must be a Function Handle or M-file Name.') 145 | end 146 | 147 | xc=varargin{2}; % Xo 148 | 149 | if nargin>2 % OPTIONS 150 | if isstruct(varargin{3}) 151 | options=varargin{3}; 152 | else 153 | if ~exist('options','var') 154 | options = LMFsolveOLD('default'); 155 | end 156 | for i=3:2:size(varargin,2)-1 157 | options=LMFsolveOLD(options, varargin{i},varargin{i+1}); 158 | end 159 | end 160 | else 161 | if ~exist('options','var') 162 | options = LMFsolveOLD('default'); 163 | end 164 | end 165 | 166 | x=xc(:); 167 | lx=length(x); 168 | 169 | r=feval(FUN,x); % Residuals at starting point 170 | %~~~~~~~~~~~~~~ 171 | S=r'*r; 172 | epsx=options.XTol(:); 173 | epsf=options.FunTol(:); 174 | if length(epsx)1 188 | D=diag(sqrt(abs(D(1:lx)))); % vector of individual scaling 189 | else 190 | D=sqrt(abs(D))*eye(lx); % scalar of unique scaling 191 | end 192 | end 193 | 194 | Rlo=0.25; Rhi=0.75; 195 | l=1; lc=.75; is=0; 196 | cnt=0; 197 | ipr=options.Display; 198 | printit(-1); % Table header 199 | d=options.XTol; % vector for the first cycle 200 | maxit = options.MaxIter; % maximum permitted number of iterations 201 | 202 | while cnt=epsx) && ... %%%%%%%%%%%%%%%%%%%% 204 | any(abs(r)>=epsf) 205 | d=(A+l*D)\v; % negative solution increment 206 | xd=x-d; 207 | rd=feval(FUN,xd); 208 | % ~~~~~~~~~~~~~~~~~ 209 | Sd=rd.'*rd; 210 | dS=d.'*(2*v-A*d); % predicted reduction 211 | R=(S-Sd)/dS; 212 | 213 | if R>Rhi 214 | l=l/2; 215 | if l10 221 | nu=10; 222 | end 223 | if l==0 224 | lc=1/max(abs(diag(inv(A)))); 225 | l=lc; 226 | nu=nu/2; 227 | end 228 | l=nu*l; 229 | end 230 | cnt=cnt+1; 231 | if ipr>0 && (rem(cnt,ipr)==0 || cnt==1) 232 | printit(cnt,[S,l,R,x(:).']) 233 | printit(0,[lc,d(:).']) 234 | end 235 | if Sd>S && is==0 236 | is=1; 237 | St=S; xt=x; rt=r; Jt=J; At=A; vt=v; 238 | end 239 | if Sd0 240 | S=Sd; x=xd; r=rd; 241 | J=options.Jacobian(FUN,r,x,epsx); 242 | % ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 243 | A=J.'*J; v=J.'*r; 244 | else 245 | S=St; x=xt; r=rt; J=Jt; A=At; v=vt; 246 | end 247 | if Sd0 print out first row of results 260 | 261 | if ipr>0 262 | if cnt<0 % table header 263 | disp('') 264 | disp(char('*'*ones(1,100))) 265 | disp([' cnt SUM(r^2) l R' blanks(21) 'x(i) ...']) 266 | disp([blanks(24) 'lc' blanks(32) 'dx(i) ...']) 267 | disp(char('*'*ones(1,100))) 268 | disp('') 269 | else % iteration output 270 | if cnt>0 || rem(cnt,ipr)==0 271 | f='%12.4e '; 272 | form=[f f f f '\n' blanks(49)]; 273 | if cnt>0 274 | fprintf(['%4.0f ' f f f ' x = '],[cnt,mx(1:3)]) 275 | fprintf(form,mx(4:length(mx))) 276 | else 277 | fprintf([blanks(18) f blanks(13) 'dx = '], mx(1)) 278 | fprintf(form,mx(2:length(mx))) 279 | end 280 | fprintf('\n') 281 | end 282 | end 283 | end 284 | end 285 | 286 | % FINJAC numerical approximation to Jacobi matrix 287 | % %%%%%% 288 | function J = finjac(FUN,r,x,epsx) 289 | %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 290 | lx=length(x); 291 | J=zeros(length(r),lx); 292 | for k=1:lx 293 | dx=.25*epsx(k); 294 | xd=x; 295 | xd(k)=xd(k)+dx; 296 | rd=feval(FUN,xd); 297 | % ~~~~~~~~~~~~~~~~ 298 | J(:,k)=((rd-r)/dx); 299 | end 300 | end 301 | end -------------------------------------------------------------------------------- /LMFsolvetest.m: -------------------------------------------------------------------------------- 1 | % LMFsolvetest Test of the function LMFtest 2 | % ~~~~~~~~~~~~ { default = Rosenbrock } 2009-01-08 3 | 4 | x = inp('Starting point [xo]',[-1.2; 1]); 5 | x = x(:); 6 | lx = length(x); 7 | fun = inp('Function name ','rosen'); 8 | D = eval(inp('vektor vah [D]','1')); 9 | ipr = inp('Print control ipr',1); 10 | 11 | resid = eval(['@' fun]); % function handle 12 | options = LMFsolve('default'); 13 | options = LMFsolve... 14 | (options,... 15 | 'XTol',1e-6,... 16 | 'FTol',1e-12,... 17 | 'ScaleD',D,... 18 | 'Display',ipr... 19 | ); 20 | [x,S,cnt]=LMFsolve(resid,x,options); 21 | % ~~~~~~~~~~~~~~~~~~~~~~~~~ 22 | 23 | fprintf('\n radius = %15.8e\n', sqrt(x'*x)); 24 | 25 | -------------------------------------------------------------------------------- /LevenbergMarquardt.m: -------------------------------------------------------------------------------- 1 | function [xCurrent,Resnorm,fval,exitflag,extra_arguments,output,lambda,Jx] =LevenbergMarquardt(obj,xGuess,lb,ub,opt) 2 | %% LEVENBERG-MARQUARD ALGORITHM WITH BROYDEN UPDATES FOR THE JACOBIAN 3 | % 4 | % LevenbergMarquardt is similar to lsqnonlin with the levenberg-marquardt 5 | % algorithm with the three main advantages: 6 | % 7 | % 1) the jacobian can be updated using the Broyden method which 8 | % minimizes function evaluations 9 | % 2) the variables are transformed to implement box-constraints, and 10 | % 3) function arguments can be passed on. 11 | % 12 | % Some functionality is very similar, others differ slightly. 13 | % 14 | % syntax: 15 | % 16 | % xCurrent=LevenbergMarquardt(obj,xGuess); 17 | % xCurrent=LevenbergMarquardt(obj,xGuess,lb); 18 | % xCurrent=LevenbergMarquardt(obj,xGuess,lb,ub); 19 | % xCurrent=LevenbergMarquardt(obj,xGuess,lb,ub,opt); 20 | % 21 | % where obj and xGuess are the objective function and the inital guess. 22 | % lb and ub are the box constraints and can be left empty, or set to 23 | % infinity or -infinity, respectively, if no constraints are binding. opt 24 | % allows to pass on other arguments as explained below. 25 | % 26 | % example: 27 | % 28 | % as an example we can fit a 2-degree taylor on a sin function in the 29 | % unit interval: 30 | % xGuess=ones(1,3); 31 | % x=linspace(0,1)'; 32 | % curve=@(para)para(1)+para(2).*x+para(3).*x.^2; 33 | % obj=@(para)[sin(x)-curve(para)]; 34 | % lets exploit some functionalities: 35 | % opt.Display='iter'; 36 | % opt.title='curve fitting for sin function'; 37 | % lets assume we are interested in how good the fit looks outside the 38 | % fitted range (1,2) 39 | % opt.pltfn=@(para)[sin(x+1)-para(1)+para(2).*(x+1)+para(3).*(x+1).^2]; 40 | % lets use the jacobian method that exploits romberg extrapolation (more 41 | % precise generally) 42 | % opt.Jacobian='romberg'; 43 | % xCurrent =LevenbergMarquardt(obj,xGuess,[],[],opt); 44 | % figure 45 | % plot(x,[sin(x) curve(xCurrent)]) 46 | % lets restrict all parameters to be positive and shut off the broyden 47 | % type updates. 48 | % opt.Broyden_updates='off'; 49 | % xCurrent2=LevenbergMarquardt(obj,xCurrent,zeros(1,3),[],opt); 50 | % plot(x,[sin(x) curve(xCurrent) curve(xCurrent2)]) 51 | % legend('sin','curve fit','curve fit with restrictions') 52 | % 53 | % There is another example attached to this file that deals explicitly 54 | % with argument passing. 55 | % 56 | % author: Alexander.Dentler at gmail.com, October 9th 2015, all errors 57 | % are yours to deal with. 58 | % 59 | % version 3 60 | 61 | %% INITIAL PARAMETER READ IN 62 | xForm=xGuess; 63 | n = numel(xGuess); 64 | xGuess=xGuess(:); 65 | t1=cputime; 66 | if exist('lb','var') 67 | if isempty(lb) 68 | lb=-inf(size(xForm)); 69 | end 70 | else 71 | lb=-inf(size(xForm)); 72 | end 73 | if exist('ub','var') 74 | if isempty(ub) 75 | ub=inf(size(xForm)); 76 | end 77 | else 78 | ub=inf(size(xForm)); 79 | end 80 | %% DEFAULT PARAMETERS 81 | % display 82 | Display='none'; % different degrees of notifications, default gives final output 83 | title=[]; % user can add a title that will show up before the iteration (and renewals of the header) and on the figure name 84 | IterDispRenewal=30; % renew header of iterative display after so many steps 85 | OutputFcn=[]; % collects user specified output function which is either a function handle or a cell array with functions in each cell 86 | PlotIterations=0; % create plots at each iteration 87 | pltfn=[]; % user can supply one function which takes x as an argument and plots it values 88 | % passing arguments 89 | extra_arguments=cell(1,0); % arguments created with each iteration that is passed as argument in the next iteration (for nested iterations) 90 | % iteration and function count 91 | MaxIter=200*n; % maximal no of iterations 92 | MaxFunEvals=200*n; % maximal no of function calls 93 | % acceptance tolerances 94 | AccTol=0; % breakup optimization if Resnorm is below this value (accept function value) 95 | FooTol=1e-7; % breakup optimization if gradients are below this value (first order optimality condition) 96 | RelFooTol=1e-6; % breakup optimization if relative gradients are below this value (first order optimality condition) 97 | IncrTol=1e-6; % new evaluated point shows enough improvement to be fully accepted and lambda does not decrease 98 | TolFun=NaN; % breakup optimization if absolute Resnorm improvement falls below this level 99 | RelTolFun=NaN; % breakup optimization if relative Resnorm improvement falls below this level 100 | TolX=1e-7; % breakup optimization if all absolute changes in parameters fall below this level 101 | RelTolX=1e-5; % breakup optimization if all relative changes in parameters fall below this level 102 | % Levenberg-Marquardt parameters 103 | Jacobian='off'; % user supplies jacobian as second output argument of fun if set to 'on', otherwise 'off' (default) 104 | MaxStepNo=2; % no of steps taken to find jacobian when "Jacobiab" is set to 'limit' or 'extrapolation' 105 | FinDiffRelStep=eps^(1/3); % multiplies step size of non-supplied Jacobian finite difference step 106 | TypicalX=1; % scales step size of non-supplied Jacobian finite difference step 107 | DerivativeCheck='off'; % if set to 'on' it checks Jacobian in first step 108 | ScaleProblem='Jacobian'; % if set to 'Jacobian' the problem is rescaled, by 'none' its not. 109 | InitDamping=1e-2; % initial dampening 110 | MinDamping=1e-7; % minimal dampening 111 | MaxDamping=1e7; % maximal dampening 112 | FactDamping=10; % increases or decreases dampening in loop 113 | MaxEigTol=1e-6; % if largest eigenvalue becomes smaller than this value we attempt to use contraction mapping 114 | Broyden_updates='on'; % set to 'on' it gives Broyden updates for the Jacobian for every 2*n steps, set to 'off' it requires updates in each iteration, 115 | % set to an integer thats the amount of steps until we update 116 | conservative_updates=1; % set to 1 it will only enforce the tolerances for foo, stepsize or eigenvalue when we just updated Jacobian 117 | %% DYNAMIC READ IN OF STRUCTURE THAT GIVES OPTIONS 118 | fval=[];J=[]; 119 | if nargin>=5 % optional parameter structure opt has been provided 120 | if isstruct(opt) 121 | list=who; 122 | %% check specifically if bounds are also given in option structure 123 | % and check if they are identical, otherwise give error 124 | if isfield(opt, 'lb') 125 | if ~isequal(opt.lb(:),lb(:)) && ~isequal(-inf(numel(xGuess),1),lb(:)) 126 | error('Lower bounds given are not identical to lower bounds in option structure.') 127 | end 128 | end 129 | if isfield(opt, 'ub') 130 | if ~isequal(opt.ub(:),ub(:)) && ~isequal(inf(numel(xGuess),1),ub(:)) 131 | error('Upper bounds given are not identical to upper bounds in option structure.') 132 | end 133 | end 134 | %% dynamic read in 135 | for i1=1:numel(list) 136 | if isfield(opt, char(list{i1})) 137 | eval(horzcat(matlab.lang.makeValidName(char(list(i1))),'=opt.',char(list{i1}),';')); 138 | end 139 | end 140 | end 141 | end 142 | %% ERROR CHECKING AND PREP 143 | % boundary error check 144 | if (numel(lb)>0 || numel(lb)>0) && (numel(xGuess)~=numel(lb) || numel(xGuess)~=numel(ub)) || any(lb(:)>=ub(:)) 145 | error('Number of bounds does not correspond to number of variable to optimize, or bounds are reversed.') 146 | end 147 | lb=lb(:); 148 | ub=ub(:); 149 | if any(xGuessub) 150 | warning('The guess is outside the specified domain. We correct for this. But don''t let that happen again.') 151 | xGuess(xGuessub)=lb(xGuess>ub)-eps; 153 | end 154 | % transformations 155 | yGuess=bnd2unbnd(xGuess,lb,ub); 156 | transformback=@(y)unbnd2bnd(y,lb,ub); 157 | % objective 158 | objx=@(x,vara)obj(reshape(x,size(xForm)),vara{:}); 159 | objy=@(y,vara)obj(reshape(transformback(y),size(xForm)),vara{:}); 160 | % Jacobian matter 161 | switch Jacobian 162 | case 'limit' 163 | Jacobian_method=2; 164 | case {'extrapolation','romberg'} 165 | Jacobian_method=3; 166 | case 'on' 167 | Jacobian_method=4; 168 | otherwise 169 | Jacobian_method=1; 170 | end 171 | option_Jacobian.Jacobian_method=Jacobian_method; 172 | option_Jacobian.FinDiffRelStep=FinDiffRelStep; 173 | option_Jacobian.TypicalX=TypicalX; 174 | option_Jacobian.MaxStepNo=MaxStepNo; 175 | option_Jacobian.lb=lb; 176 | option_Jacobian.ub=ub; 177 | if ~isscalar(Broyden_updates) 178 | if ischar(Broyden_updates) 179 | switch Broyden_updates 180 | case 'off' 181 | Broyden_updates=0; 182 | otherwise 183 | Broyden_updates=2*n; 184 | end 185 | end 186 | end 187 | % dampening 188 | lambda=InitDamping;lambda_old=InitDamping; 189 | % display 190 | switch Display 191 | case {'notify','notify-detailed'} 192 | prnt = 1; 193 | case {'none','off'} 194 | prnt = 0; 195 | case {'iter','iter-detailed'} 196 | prnt = 3; 197 | case {'final','final-detailed'} 198 | prnt = 2; 199 | case 'simplex' 200 | prnt = 4; 201 | otherwise 202 | prnt = 1; 203 | end 204 | option_Jacobian.dsp=2*(prnt==3)+(prnt==4); 205 | prnt_fun=@(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,how)fprintf('%4.0f %4.0f % 8.2g % 8.2g % 8.2g % 8.2g % 8.2g % 8.2g % 8.2g % 8.2g % 8.2g % 8.2g % 8.2g %s \n',x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,how); 206 | txt=['\n Norm Rel norm First-order Rel first-order Largest Comment\n',... 207 | ' I# F# f(x) Df(x) relDf(x) of step of step optimality optimality eigenvalue lambda rho ratio ']; 208 | header_wo_title=sprintf(txt); 209 | if ~isempty(title) 210 | header = sprintf(horzcat('\n',title,txt)); 211 | else 212 | header = header_wo_title; 213 | end 214 | %% STARTING VALUES 215 | flag_nochange=1; 216 | h=NaN(n,1);E=NaN(n,1); 217 | iteration=0;funccount=1;Jacobian_counter=1;how='Initial evaluation'; 218 | xLMstep=NaN(n,1);yLMstep=NaN(n,1);newtonianstep=NaN(n,1);xgradient=NaN(n,1); 219 | rho=NaN;ratio=NaN;fun_improv=NaN;rel_fun_improv=NaN;maxFoo=NaN;maxrelFoo=NaN; 220 | maxabsstep=NaN;maxabsrelstep=NaN;MaxEigJJ=NaN; 221 | % first evaluation 222 | if ~isempty(fval) && (~isempty(J) || (isempty(J) && Jacobian_method<4)) 223 | Resnorm=sum(fval.^2); 224 | else 225 | [fval,Resnorm,J,extra_arguments]=eval_fun(objy,yGuess,Jacobian_method,extra_arguments); 226 | end 227 | option_Jacobian.m=numel(fval); 228 | % initial display 229 | if prnt>1 230 | disp(header) 231 | prnt_fun(MaxIter,MaxFunEvals,AccTol,TolFun,RelTolFun,TolX,RelTolX,FooTol,RelFooTol,... 232 | MaxEigTol,MaxDamping,IncrTol,NaN,'Thresholds'); 233 | prnt_first={iteration,funccount,Resnorm,fun_improv,rel_fun_improv,maxabsstep,maxabsrelstep,maxFoo,maxrelFoo,... 234 | MaxEigJJ,lambda,rho,ratio,how}; 235 | prnt_fun(prnt_first{:}); 236 | end 237 | % good staring values? 238 | if any(~isfinite(fval)) 239 | disp('staring values: ') 240 | disp(num2str(unbnd2bnd(yGuess,lb,ub))) 241 | disp('fval: ') 242 | disp(num2str(fval)) 243 | error('Some starting value is not finite.') 244 | end 245 | % derivative check 246 | if strcmp(DerivativeCheck,'on') && Jacobian_method==4 247 | option_Jacobian_check=option_Jacobian; 248 | option_Jacobian_check.Jacobian_method=3; 249 | J_check=eval_Jacobian(@(x)objx(x,extra_arguments),yGuess,fval,option_Jacobian_check); 250 | dh=D_unbnd2bnd(yGuess,lb,ub); 251 | err=bsxfun(@times,(J-J_check),1./dh); 252 | relerr=err./bsxfun(@plus,abs(transformback(yGuess)),abs(transformback(yGuess)'))/2; 253 | disp(horzcat('Derivative check gives largest error with ',... 254 | num2str(max(err(:))),' and largest relative error with ',num2str(max(relerr(:))))) 255 | end 256 | %% DYNAMIC LOOP TO OPTIMIZE 257 | % initial call of output functions and plotting function 258 | OtptFcnVl.xInit=xGuess;OtptFcnVl.fvalInit=fval; 259 | OtptFcnVl.pltfn=pltfn;OtptFcnVl.transformback=transformback; 260 | OtptFcnVl.xForm=xForm;OtptFcnVl.title=title; 261 | OtptFcnVl.ResnormHist=Resnorm; 262 | 263 | OtptFcnVl.iteration=iteration;OtptFcnVl.funccount=funccount; 264 | OtptFcnVl.Jacobian_counter=Jacobian_counter;OtptFcnVl.fval=fval; 265 | OtptFcnVl.Resnorm=Resnorm;OtptFcnVl.J=J;OtptFcnVl.h=h;OtptFcnVl.E=E; 266 | OtptFcnVl.xLMstep=xLMstep;OtptFcnVl.yLMstep=yLMstep; 267 | OtptFcnVl.newtonianstep=newtonianstep;OtptFcnVl.xgradient=xgradient; 268 | OtptFcnVl.extra_arguments=extra_arguments; 269 | 270 | OtptFcnVl.rho=rho;OtptFcnVl.ratio=ratio;OtptFcnVl.lambda=lambda; 271 | OtptFcnVl.fun_improv=fun_improv;OtptFcnVl.rel_fun_improv=rel_fun_improv; 272 | OtptFcnVl.maxFoo=maxFoo;OtptFcnVl.maxrelFoo=maxrelFoo; 273 | OtptFcnVl.maxabsstep=maxabsstep;OtptFcnVl.maxabsrelstep=maxabsrelstep; 274 | OtptFcnVl.MaxEigJJ=MaxEigJJ; 275 | % callup functions 276 | stop=eval_outputfun(OutputFcn,transformback(yGuess),OtptFcnVl,'init'); 277 | if PlotIterations 278 | OtptFcnVl=eval_PlotIterations(transformback(yGuess),OtptFcnVl,'init'); 279 | end 280 | % loop 281 | howJ='user-supplied Jacobian'; 282 | while Resnorm>AccTol && funccount< MaxFunEvals && iteration < MaxIter && stop==false 283 | %% INITIALIZE ITERATION 284 | iteration=iteration+1; 285 | maxabsstep=NaN;maxabsrelstep=NaN;MaxEigJJ=NaN; 286 | rho=NaN;ratio=NaN;fun_improv=NaN;rel_fun_improv=NaN; 287 | %% evaluate Jacobian at current point 288 | dh=D_unbnd2bnd(yGuess,lb,ub); 289 | if isempty(J) && Jacobian_method<4 290 | [J,h,E,func_evals_Jacobian]=eval_Jacobian(@(x)objx(x,extra_arguments),yGuess,fval,option_Jacobian); 291 | funccount=funccount+func_evals_Jacobian; 292 | Jacobian_counter=1; 293 | howJ='full Jacobian update'; 294 | end 295 | how=howJ; 296 | if prnt==4 297 | disp('Jacobian:') 298 | disp(num2str(bsxfun(@times,J,1./dh))) % transform back to x space 299 | if Jacobian_method==2 || Jacobian_method==3 300 | disp('step size for Jacobian:') 301 | disp(num2str(h)) 302 | disp('Error size:') 303 | disp(num2str(E)) 304 | end 305 | end 306 | %% evaluate first order optimatlity 307 | xgradient=bsxfun(@times,-J,1./dh)'*fval; 308 | relFoo=xgradient./(1e-12+abs(transformback(yGuess))); 309 | maxFoo=max(abs(xgradient)); 310 | maxrelFoo=max(abs(relFoo)); 311 | if (maxFooIncrTol || TolFun>fun_improv || RelTolFun>rel_fun_improv 372 | % note 373 | how=horzcat('*',how); 374 | % good evaluation, decrease dampening 375 | lambda=max(lambda/FactDamping,MinDamping); 376 | flag_nochange=0; 377 | %% Jacobian update 378 | if Jacobian_method==4 379 | %% user supplied function also updated Jacobian 380 | J=LM_J; 381 | howJ='user-supplied Jacobian'; 382 | else 383 | %% update jacobian or destroy it 384 | Jacobian_counter=Jacobian_counter+1; 385 | if Jacobian_counter>=Broyden_updates || isempty(J)%(2*n) || ~Broyden_updates 386 | J=[]; 387 | howJ='full Jacobian update'; 388 | else 389 | J=J+((LM_fval-fval-J*yLMstep)*yLMstep')/(yLMstep'*yLMstep); 390 | howJ='Broyden-type update'; 391 | end 392 | end 393 | %% other values 394 | fval=LM_fval; 395 | Resnorm=LM_Resnorm; 396 | yGuess=yGuess+yLMstep; 397 | extra_arguments=LM_extra_arguments; 398 | elseif lambda==MaxDamping && (Jacobian_counter<=2 || ~conservative_updates) 399 | how='dampening'; 400 | break 401 | else 402 | % bad evaluation, increase dampening 403 | if Jacobian_counter>1 && Jacobian_method<4 && lambda==MaxDamping 404 | J=[]; 405 | lambda=InitDamping; 406 | howJ='full Jacobian update'; 407 | elseif Jacobian_counter>1 && Jacobian_method<4 408 | % quick dampening as we use a Broyden updated jacobian which 409 | % is quick, but suboptimal so we dont want to waste time with 410 | % large steps that are imprecise. 411 | lambda=min(lambda*(FactDamping^2),MaxDamping); 412 | howJ='quick dampening'; 413 | else 414 | lambda=min(lambda*FactDamping,MaxDamping); 415 | howJ='soft dampening'; 416 | end 417 | end 418 | if Resnorm<=AccTol 419 | break 420 | end 421 | %% iterative display for LM 422 | if prnt>2 423 | if mod(iteration,IterDispRenewal)==0 || IterDispRenewal==1 424 | disp(header) 425 | prnt_fun(MaxIter,MaxFunEvals,AccTol,TolFun,RelTolFun,TolX,RelTolX,FooTol,RelFooTol,... 426 | MaxEigTol,MaxDamping,IncrTol,NaN,'Thresholds'); 427 | end 428 | prnt_fun(iteration,funccount,Resnorm,fun_improv,rel_fun_improv,maxabsstep,maxabsrelstep,maxFoo,maxrelFoo,... 429 | MaxEigJJ,lambda_old,rho,ratio,how); 430 | end 431 | %% OUTPUT FUNCTIONS 432 | OtptFcnVl.ResnormHist=[OtptFcnVl.ResnormHist Resnorm]; 433 | OtptFcnVl.iteration=iteration;OtptFcnVl.funccount=funccount; 434 | OtptFcnVl.Jacobian_counter=Jacobian_counter;OtptFcnVl.fval=fval; 435 | OtptFcnVl.Resnorm=Resnorm;OtptFcnVl.J=J;OtptFcnVl.h=h;OtptFcnVl.E=E; 436 | OtptFcnVl.xLMstep=xLMstep;OtptFcnVl.yLMstep=yLMstep; 437 | OtptFcnVl.newtonianstep=newtonianstep;OtptFcnVl.xgradient=xgradient; 438 | OtptFcnVl.rho=rho;OtptFcnVl.ratio=ratio;OtptFcnVl.lambda=lambda_old; 439 | OtptFcnVl.fun_improv=fun_improv;OtptFcnVl.rel_fun_improv=rel_fun_improv; 440 | OtptFcnVl.maxFoo=maxFoo;OtptFcnVl.maxrelFoo=maxrelFoo; 441 | OtptFcnVl.maxabsstep=maxabsstep;OtptFcnVl.maxabsrelstep=maxabsrelstep; 442 | OtptFcnVl.MaxEigJJ=MaxEigJJ; 443 | OtptFcnVl.extra_arguments=extra_arguments; 444 | stop=eval_outputfun(OutputFcn,transformback(yGuess),OtptFcnVl,'iter'); 445 | if PlotIterations 446 | OtptFcnVl=eval_PlotIterations(transformback(yGuess),OtptFcnVl,'iter'); 447 | end 448 | end 449 | %% FINAL ASSIGNMENT 450 | xCurrent=reshape(transformback(yGuess),size(xForm)); 451 | OtptFcnVl.iteration=iteration;OtptFcnVl.funccount=funccount; 452 | if Resnorm<=AccTol 453 | how='FULL CONVERGENCE'; 454 | exitflag=1; 455 | elseif fun_improv>-TolFun || rel_fun_improv>-RelTolFun ... 456 | || maxFoo5 468 | output=OtptFcnVl; 469 | output.how=how; 470 | output.nochange=flag_nochange; 471 | output.maxchange=max(abs(OtptFcnVl.xInit-xCurrent(:))); 472 | output.xCurrent=xCurrent; 473 | output.time_used_in_sec=cputime-t1; 474 | if Jacobian_method<4 475 | output.algorithm='levenberg-marquardt with Broyden rank-1 updates for Jacobian'; 476 | else 477 | output.algorithm='levenberg-marquardt with user-supplied Jacobian'; 478 | end 479 | output.ErrJacobian=E; 480 | output.StepsizeJacobian=h; 481 | output.extra_arguments=extra_arguments; 482 | if nargout>7 483 | if isempty(J) && Jacobian_method<4 484 | [J,h,E,func_evals_Jacobian]=eval_Jacobian(@(x)objx(x,extra_arguments),yGuess,fval,option_Jacobian); 485 | funccount=funccount+func_evals_Jacobian; 486 | end 487 | dh=D_unbnd2bnd(yGuess,lb,ub); 488 | Jx=bsxfun(@times,J,1./dh); 489 | output.firstorder=(Jx'*fval); 490 | output.firstorderopt=max(abs((Jx'*fval))); 491 | output.Jacobian=Jx; 492 | end 493 | end 494 | % close things 495 | eval_outputfun(OutputFcn,transformback(yGuess),OtptFcnVl,'done'); 496 | if PlotIterations 497 | eval_PlotIterations(transformback(yGuess),OtptFcnVl,'done'); 498 | end 499 | if prnt>0 500 | if prnt==3 501 | if iteration>1 502 | disp(header) 503 | end 504 | prnt_fun(MaxIter,MaxFunEvals,AccTol,TolFun,RelTolFun,TolX,RelTolX,FooTol,RelFooTol,... 505 | MaxEigTol,MaxDamping,IncrTol,NaN,'Thresholds'); 506 | prnt_fun(prnt_first{:}) 507 | elseif prnt==1 508 | disp(header_wo_title) 509 | %prnt_fun(prnt_first{:}) 510 | end 511 | prnt_fun(iteration,funccount,Resnorm,fun_improv,rel_fun_improv,maxabsstep,maxabsrelstep,maxFoo,maxrelFoo,... 512 | MaxEigJJ,lambda_old,rho,ratio,how); 513 | end 514 | end 515 | 516 | function [fval,Resnorm,J,extra_arguments]=eval_fun(objy,yGuess,Jacobian_method,extra_arguments) 517 | %% evaluate 518 | J=[]; 519 | argu_out=cell(1,1+(Jacobian_method==4)+numel(extra_arguments)); 520 | [argu_out{:}]=objy(yGuess,extra_arguments); 521 | fval=argu_out{1}; 522 | % Jacobian 523 | if Jacobian_method==4; 524 | J=argu_out{2}; 525 | end 526 | % if we got extra arguments 527 | if numel(extra_arguments)>0 528 | [extra_arguments{:}]=deal(argu_out{2+(Jacobian_method==4):end}); 529 | end 530 | Resnorm=sum(fval.^2); 531 | end 532 | 533 | function [J,h,E,func_evals_Jacobian]=eval_Jacobian(objx,yGuess,fval,option_Jacobian) 534 | %% prep structure 535 | lb=option_Jacobian.lb; 536 | ub=option_Jacobian.ub; 537 | xGuess=unbnd2bnd(yGuess,lb,ub); 538 | Jacobian_method=option_Jacobian.Jacobian_method; 539 | if any(lb==xGuess) || any(ub==xGuess) 540 | Jacobian_method=1; 541 | end 542 | option_Jacobian.f_0=fval; 543 | %% evaluate Jacobian 544 | switch Jacobian_method 545 | case 1 546 | E=[]; 547 | [J,h,func_evals_Jacobian]=jacobiansimple(objx,xGuess,option_Jacobian); 548 | case 2 549 | [J,h,func_evals_Jacobian,E]=jacobianlim(objx,xGuess,option_Jacobian); 550 | case 3 551 | [J,h,func_evals_Jacobian,E]=jacobianext(objx,xGuess,option_Jacobian); 552 | end 553 | %% transform back to y space 554 | df=D_unbnd2bnd(yGuess,lb,ub); 555 | J=bsxfun(@times,J,df); 556 | end 557 | 558 | function stop=eval_outputfun(OutputFcn,xGuess,optimValues,state) 559 | stop=false; 560 | if ~isempty(OutputFcn) 561 | if isa(OutputFcn,'function_handle') 562 | stop = OutputFcn(xGuess,optimValues,state); 563 | elseif isa(OutputFcn,'cell') 564 | stop=false(numel(OutputFcn),1); 565 | for i1=1:numel(OutputFcn) 566 | stop(i1)= OutputFcn{i1}(xGuess,optimValues,state); 567 | end 568 | stop=any(stop); 569 | end 570 | end 571 | end 572 | 573 | function OtptFcnVl=eval_PlotIterations(xGuess,OtptFcnVl,state) 574 | xForm=OtptFcnVl.xForm; 575 | switch state 576 | case 'init' 577 | fig=figure; 578 | % optional figure name 579 | if ~isempty(OtptFcnVl.title) 580 | set(fig,'Name',OtptFcnVl.title) 581 | end 582 | subp(1)=subplot(3,2,1,'Parent',fig);title('current x');hold('on'); 583 | bar(1:numel(xGuess),xGuess,'Parent',subp(1)); 584 | 585 | subp(2)=subplot(3,2,2,'Parent',fig);title('current fval');hold('on'); 586 | plot(1:numel(OtptFcnVl.fval),OtptFcnVl.fval,'Parent',subp(2)); 587 | xlim(subp(2),[1 numel(OtptFcnVl.fval)]) 588 | 589 | subp(3)=subplot(3,2,3,'Parent',fig);title('change from initial x');hold('on'); 590 | subp(4)=subplot(3,2,4,'Parent',fig);title('change from initial fval');hold('on'); 591 | subp(5)=subplot(3,2,5,'Parent',fig);title('attempted step');hold('on'); 592 | 593 | if ~isempty(OtptFcnVl.pltfn) 594 | xForm(:)=xGuess; 595 | subp(6)=subplot(3,2,6,'Parent',fig);title('user-supplied');hold('on'); 596 | temp=OtptFcnVl.pltfn(xForm); 597 | plot(temp,'Parent',subp(6)); 598 | xlim(subp(6),[1 size(temp,1)]) 599 | else 600 | subp(6)=subplot(3,2,4,'Parent',fig);title('history residual norm');hold('on'); 601 | end 602 | OtptFcnVl.fig=fig; 603 | OtptFcnVl.subp=subp; 604 | pause(.001) 605 | case 'iter' 606 | for i1=1:numel(OtptFcnVl.subp) 607 | delete(get(OtptFcnVl.subp(i1), 'Children')); 608 | end 609 | % parameter values 610 | bar(1:numel(xGuess),xGuess,'Parent',OtptFcnVl.subp(1)); 611 | xlim(OtptFcnVl.subp(1),[.5 numel(xGuess)+.5]) 612 | % residuals 613 | plot(1:numel(OtptFcnVl.fval),OtptFcnVl.fval,'Parent',OtptFcnVl.subp(2)); 614 | xlim(OtptFcnVl.subp(2),[1 numel(OtptFcnVl.fval)]) 615 | % change in parameter values from start 616 | bar(1:numel(xGuess),xGuess-OtptFcnVl.xInit,'Parent',OtptFcnVl.subp(3)); 617 | xlim(OtptFcnVl.subp(3),[.5 numel(xGuess)+.5]) 618 | % change in residuals from start 619 | plot(1:numel(OtptFcnVl.fval),OtptFcnVl.fval-OtptFcnVl.fvalInit,'Parent',OtptFcnVl.subp(4)); 620 | xlim(OtptFcnVl.subp(4),[1 numel(OtptFcnVl.fval)]) 621 | % attempted step 622 | bar(1:numel(xGuess),OtptFcnVl.xLMstep(:),'Parent',OtptFcnVl.subp(5)); 623 | xlim(OtptFcnVl.subp(5),[.5 numel(xGuess)+.5]) 624 | % user supplied function 625 | if ~isempty(OtptFcnVl.pltfn) 626 | xForm(:)=xGuess; 627 | temp=OtptFcnVl.pltfn(xForm); 628 | plot(temp,'Parent',OtptFcnVl.subp(6)); 629 | xlim(OtptFcnVl.subp(6),[1 size(temp,1)]) 630 | else 631 | plot(OtptFcnVl.ResnormHist,'Parent',OtptFcnVl.subp(6)); 632 | end 633 | OtptFcnVl.fig=OtptFcnVl.fig; 634 | OtptFcnVl.subp=OtptFcnVl.subp; 635 | pause(.001) 636 | case 'done' 637 | % Cleanup of plots, guis, or final plot 638 | close(OtptFcnVl.fig); 639 | otherwise 640 | end 641 | end 642 | 643 | function X=unbnd2bnd(Y,lb,ub) 644 | %% transforms variable from -infinity to infinity to domain [lb,ub] 645 | % complements bnd2unbnd 646 | X=NaN(size(Y)); 647 | for i1=1:numel(Y) 648 | if isfinite(lb(i1)) && isfinite(ub(i1)) % lower and upper bound 649 | X(i1) = (lb(i1)+ub(i1))/2+ (ub(i1)-lb(i1))/2*sin(2*Y(i1)/(ub(i1)-lb(i1))); 650 | % X(i1) = max(lb(i1),min(ub(i1),(sin(Y(i1))+1)/2.*(ub(i1) - lb(i1)) + lb(i1))); 651 | % X(i1)=((atan(Y(i1))+pi/2)/pi).*(ub(i1)-lb(i1))+lb(i1); 652 | elseif isfinite(lb(i1)) && ~isfinite(ub(i1)) % just lower bound 653 | X(i1)= lb(i1)-1 + sqrt(Y(i1).^2+1); 654 | % X(i1)= lb(i1) + Y(i1).^2; 655 | % X(i1)=exp(Y(i1))+lb(i1)-eps; 656 | elseif ~isfinite(lb(i1)) && isfinite(ub(i1)) % just upper bound 657 | X(i1)= ub(i1)+1 - sqrt(Y(i1).^2+1); 658 | % X(i1)=ub(i1)-Y(i1).^2 ; 659 | % X(i1)=-exp(-Y(i1))+ub(i1)+eps; 660 | else % no bounds 661 | X(i1)=Y(i1); 662 | end 663 | end 664 | end 665 | 666 | function Y=bnd2unbnd(X,lb,ub) 667 | %% transforms variable from [lb,ub] to domain -infinity to infinity 668 | % complements unbnd2bnd 669 | Y=NaN(size(X)); 670 | for i1=1:numel(X) 671 | if isfinite(lb(i1)) && isfinite(ub(i1)) % bounded on both ends 672 | Y(i1)=(ub(i1)-lb(i1))/2*asin((2*X(i1)-(ub(i1)+lb(i1)))/(ub(i1)-lb(i1))); 673 | % Y(i1) = 2*pi+asin(max(-1,min(1,2*(X(i1) - lb(i1))/(ub(i1)-lb(i1)) - 1))); 674 | % Y(i1)=tan((X(i1)-lb(i1))./(ub(i1)-lb(i1))*pi-pi/2); 675 | elseif isfinite(lb(i1)) && ~isfinite(ub(i1)) % just lower bound 676 | Y(i1)=sqrt((lb(i1) -1 - X(i1)).^2-1); 677 | % Y(i1) = sqrt(X(i1)-lb(i1)); 678 | % Y(i1)=log(X(i1)-lb(i1)+eps); 679 | elseif ~isfinite(lb(i1)) && isfinite(ub(i1)) % just upper bound 680 | Y(i1)=sqrt((ub(i1) +1 - X(i1)).^2-1); 681 | % Y(i1) = sqrt(ub(i1) - X(i1)); 682 | % Y(i1)=-log(-X(i1)+ub(i1)+eps); 683 | else % no boundaries 684 | Y(i1)=X(i1); 685 | end 686 | end 687 | end 688 | 689 | function df=D_unbnd2bnd(Y,lb,ub) 690 | %% transform back to y space 691 | df=NaN(1,numel(Y)); 692 | for i1=1:numel(Y) 693 | if isfinite(lb(i1)) && isfinite(ub(i1)) % lower and upper bound 694 | df(i1) = cos(2*Y(i1)/(ub(i1)-lb(i1))); 695 | elseif isfinite(lb(i1)) && ~isfinite(ub(i1)) % just lower bound 696 | df(i1)= Y(i1)/sqrt(Y(i1).^2+1); 697 | elseif ~isfinite(lb(i1)) && isfinite(ub(i1)) % just upper bound 698 | df(i1)= -Y(i1)/sqrt(Y(i1).^2+1); 699 | else % no bounds 700 | df(i1)=1; 701 | end 702 | end 703 | end 704 | 705 | -------------------------------------------------------------------------------- /METH-ACET.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pngts/Nonlinear-parameter-estimation-in-thermodynamic-models/93bd1a062f616e61b0d7214b293b14d48dd16c81/METH-ACET.xlsx -------------------------------------------------------------------------------- /NONuniMUTA.m: -------------------------------------------------------------------------------- 1 | function [ Du_new] = NONuniMUTA(MAX,MIN,Du_old,gi,G ) 2 | %UNTITLED Summary of this function goes here 3 | % Detailed explanation goes here 4 | numb1=rand; 5 | 6 | 7 | ra=rand; 8 | if numb1>0.5 9 | %afksanete 10 | Du_new=Du_old+(MAX-Du_old)*(1-ra^(1-gi/G)); 11 | else 12 | %mionete 13 | Du_new=Du_old-(Du_old-MIN)*(1-ra^(1-gi/G)); 14 | 15 | end 16 | 17 | -------------------------------------------------------------------------------- /Psat.m: -------------------------------------------------------------------------------- 1 | function Psat() 2 | %This function looks up the Antoine constants by id and 3 | %calculates the vapor pressure (mmHg) at a specified temperature (in C). 4 | %Use 'run AntoineTableBrowse' for a quick overview of available constants. 5 | [names A B C] = AntoineGet([4 8]) 6 | T = 100; %T in C 7 | disp(sprintf('T(C) %g', T)) 8 | P =10.^(A-B./(T+C)); 9 | disp(sprintf('Psat(mmHg) %g ',P)) 10 | end -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Nonlinear-parameter-estimation-in-thermodynamic-models 2 | The reliable solution of nonlinear parameter estimation problems is an essential computational and mathematical problem in process systems engineering, both in on-line and off-line applications. Parameter estimation in semi-empirical models for vapor – liquid equilibrium (VLE) data modelling plays an important role in design, optimization and control of separation units. Conventional optimisation methods may not be reliable since they do not guarantee convergence to the global optimum sought in the parameter estimation problem. In this work we demonstrate a technique, based on genetic algorithms (GA), that can solve the nonlinear parameter estimation problem with complete reliability, providing a high probability that the global optimum is found. Two versions of stochastic optimization techniques are evaluated and compared for nine vapour - liquid equilibrium problems: our genetic base algorithm and a hybrid algorithm. Reliable experimental data from the literature on vapor - liquid equilibrium systems were correlated using the UNIQUAC equation for activity coefficients. Our results indicate that this method, when properly implemented, is a robust procedure for nonlinear parameter estimation in thermodynamic models. Considering that new globally optimal parameter values are found by using the proposed method we can surmise by our results that several sets of parameter values published in the DECHEMA VLE Data Collection correspond to local instead of global minima. 3 | -------------------------------------------------------------------------------- /START_HERE.m: -------------------------------------------------------------------------------- 1 | %% EXAMPLES (insert experimental data X-Y-T-P) 2 | 3 | %insert_data_exp_TERNSET2_150_TP 4 | %insert_data_acet_chcl3_TP 5 | %insert_data_chcl3_meth_TP 6 | %insert_data__acetone_meth2_TP 7 | 8 | 9 | %insert_data_exp_TERNset1_TP 10 | %insert_data__acetone_meth_TP 11 | %insert_data_acetone_water_TP 12 | %insert_data_meth_water_TP 13 | 14 | %insert_quaternary1 15 | 16 | % insert_inglesiasTP 17 | %% 18 | hybrid_ga_fminsearch1_TP -------------------------------------------------------------------------------- /TERNARY.DAT: -------------------------------------------------------------------------------- 1 | System: ACETONE(1) - METHANOL(2) - WATER (3) 2 | 3 | T(K) P(bar) Y(1) X(1) Y(2) X(2) 4 | 373.15 3.820 0.3230 0.2700 0.6480 0.6790 5 | 373.15 3.765 0.9010 0.9160 0.0690 0.0500 6 | 373.15 3.923 0.6210 0.6070 0.3390 0.3300 7 | 373.15 3.896 0.4300 0.3810 0.5250 0.5490 8 | 373.15 3.751 0.3240 0.2570 0.6210 0.6400 9 | 373.15 3.647 0.3110 0.2310 0.6240 0.6390 10 | 373.15 3.765 0.4550 0.3850 0.4740 0.4790 11 | 373.15 3.516 0.2590 0.1770 0.6570 0.6540 12 | 373.15 3.482 0.2720 0.1820 0.6290 0.6160 13 | 373.15 3.682 0.5930 0.4940 0.2950 0.2940 14 | 373.15 3.440 0.3200 0.2010 0.5580 0.5490 15 | 373.15 3.461 0.3390 0.1900 0.5350 0.5460 16 | 373.15 3.696 0.8080 0.7700 0.0640 0.0590 17 | 373.15 3.406 0.3680 0.2200 0.4890 0.4780 18 | 373.15 3.647 0.7630 0.6720 0.0770 0.0820 19 | 373.15 3.537 0.5410 0.3790 0.2960 0.2990 20 | 373.15 3.392 0.4710 0.2750 0.3390 0.3440 21 | 373.15 3.530 0.6610 0.4600 0.1450 0.1710 22 | 373.15 3.130 0.3080 0.1440 0.4950 0.4400 23 | 373.15 2.903 0.1870 0.0750 0.5930 0.4700 24 | 373.15 3.434 0.6940 0.4440 0.0840 0.1300 25 | 373.15 3.206 0.5290 0.2520 0.2290 0.2430 26 | 373.15 3.337 0.6660 0.3610 0.0870 0.1270 27 | 373.15 2.903 0.2940 0.1030 0.4430 0.3450 28 | 373.15 3.013 0.4360 0.1670 0.3010 0.2870 29 | 373.15 3.116 0.5860 0.2320 0.1350 0.1600 30 | 373.15 2.799 0.2750 0.0910 0.4420 0.3380 31 | 373.15 2.992 0.5160 0.1780 0.1990 0.2130 32 | 373.15 3.068 0.6580 0.2150 0.0410 0.0330 33 | 373.15 2.854 0.4270 0.1280 0.2670 0.2330 34 | 373.15 2.923 0.5890 0.1580 0.0920 0.0880 35 | 373.15 2.758 0.4110 0.1000 0.2610 0.1930 36 | 373.15 2.751 0.5030 0.1190 0.1560 0.1190 37 | 373.15 2.517 0.3250 0.0690 0.3170 0.1980 38 | 373.15 2.648 0.4680 0.0890 0.1670 0.1310 39 | 373.15 2.372 0.2120 0.0430 0.4190 0.2250 40 | 373.15 2.241 0.2080 0.0330 0.4110 0.2040 41 | 373.15 2.441 0.4120 0.0660 0.1970 0.1190 42 | 373.15 2.165 0.1970 0.0280 0.3960 0.1820 43 | 373.15 1.993 0.2480 0.0240 0.2710 0.1070 44 | 373.15 2.013 0.3550 0.0310 0.1320 0.0480 45 | 373.15 1.986 0.3950 0.0310 0.0910 0.0380 46 | 373.15 1.765 0.2870 0.0190 0.1480 0.0440 47 | 373.15 1.696 0.3140 0.0190 0.0980 0.0290 48 | 373.15 1.634 0.2560 0.0150 0.1260 0.0340 49 | 373.15 1.558 0.1820 0.0080 0.1460 0.0400 50 | 373.15 1.503 0.2810 0.0100 0.0270 0.0180 51 | 373.15 1.441 0.1640 0.0070 0.1120 0.0310 52 | 373.15 1.469 0.2100 0.0090 0.0540 0.0230 53 | 373.15 1.338 0.0690 0.0010 0.1750 0.0390 54 | 373.15 1.234 0.1100 0.0010 0.0450 0.0180 55 | -------------------------------------------------------------------------------- /TERNARY_revised.DAT: -------------------------------------------------------------------------------- 1 | System: ACETONE(1) - METHANOL(2) - WATER (3) 2 | 3 | T(K) P(bar) Y(1) X(1) Y(2) X(2) 4 | 373.15 3.820 0.3230 0.2700 0.6480 0.6790 5 | 373.15 3.765 0.9010 0.9160 0.0690 0.0500 6 | 373.15 3.923 0.6210 0.6070 0.3390 0.3300 7 | 373.15 3.896 0.4300 0.3810 0.5250 0.5490 8 | 373.15 3.751 0.3240 0.2570 0.6210 0.6400 9 | 373.15 3.647 0.3110 0.2310 0.6240 0.6390 10 | 373.15 3.765 0.4550 0.3850 0.4740 0.4790 11 | 373.15 3.516 0.2590 0.1770 0.6570 0.6540 12 | 373.15 3.482 0.2720 0.1820 0.6290 0.6160 13 | 373.15 3.682 0.5930 0.4940 0.2950 0.2940 14 | 373.15 3.440 0.3200 0.2010 0.5580 0.5490 15 | 373.15 3.461 0.3390 0.1900 0.5350 0.5460 16 | 373.15 3.696 0.8080 0.7700 0.0640 0.0590 17 | 373.15 3.406 0.3680 0.2200 0.4890 0.4780 18 | 373.15 3.647 0.7630 0.6720 0.0770 0.0820 19 | 373.15 3.537 0.5410 0.3790 0.2960 0.2990 20 | 373.15 3.392 0.4710 0.2750 0.3390 0.3440 21 | 373.15 3.530 0.6610 0.4600 0.1450 0.1710 22 | 373.15 3.130 0.3080 0.1440 0.4950 0.4400 23 | 373.15 2.903 0.1870 0.0750 0.5930 0.4700 24 | 373.15 3.206 0.5290 0.2520 0.2290 0.2430 25 | 373.15 2.903 0.2940 0.1030 0.4430 0.3450 26 | 373.15 3.013 0.4360 0.1670 0.3010 0.2870 27 | 373.15 2.799 0.2750 0.0910 0.4420 0.3380 28 | 373.15 3.068 0.6580 0.2150 0.0410 0.0330 29 | 373.15 2.854 0.4270 0.1280 0.2670 0.2330 30 | 373.15 2.758 0.4110 0.1000 0.2610 0.1930 31 | 373.15 2.751 0.5030 0.1190 0.1560 0.1190 32 | 373.15 2.517 0.3250 0.0690 0.3170 0.1980 33 | 373.15 2.372 0.2120 0.0430 0.4190 0.2250 34 | 373.15 2.241 0.2080 0.0330 0.4110 0.2040 35 | 373.15 2.441 0.4120 0.0660 0.1970 0.1190 36 | 373.15 2.165 0.1970 0.0280 0.3960 0.1820 37 | 373.15 1.993 0.2480 0.0240 0.2710 0.1070 38 | 373.15 2.013 0.3550 0.0310 0.1320 0.0480 39 | 373.15 1.765 0.2870 0.0190 0.1480 0.0440 40 | 373.15 1.696 0.3140 0.0190 0.0980 0.0290 41 | 373.15 1.634 0.2560 0.0150 0.1260 0.0340 42 | 373.15 1.558 0.1820 0.0080 0.1460 0.0400 43 | 44 | -------------------------------------------------------------------------------- /Tsat.m: -------------------------------------------------------------------------------- 1 | function Tsat() 2 | %This function looks up the Antoine constants by id and 3 | %finds the saturation temperature (in C). 4 | %Use 'run AntoineTableBrowse' for a quick overview of available constants. 5 | [names A B C] = AntoineGet(3) 6 | P = 220; %pressure to match mmHg 7 | disp(sprintf('P(mmHg) %g',P)) 8 | T = fzero(@(T)(10^(A-B/(T+C))-P),25); 9 | disp(sprintf('Tsat(C) %g', T)) 10 | end -------------------------------------------------------------------------------- /benz_propylAlcho.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pngts/Nonlinear-parameter-estimation-in-thermodynamic-models/93bd1a062f616e61b0d7214b293b14d48dd16c81/benz_propylAlcho.xlsx -------------------------------------------------------------------------------- /bisection.m: -------------------------------------------------------------------------------- 1 | function [x]=bisection(f,a,b) 2 | 3 | for i=1:100 4 | if i==100 5 | x='No root in this interval.'; 6 | fprintf('\n') 7 | break; 8 | end 9 | x=(a+b)/2; 10 | 11 | if abs(f(x))<0.01 12 | break 13 | end 14 | 15 | 16 | 17 | if f(x)*f(a)<0 18 | b=x; 19 | end 20 | 21 | if f(x)*f(a)>0 22 | a=x; 23 | end 24 | 25 | 26 | end 27 | end -------------------------------------------------------------------------------- /classicsolver.m: -------------------------------------------------------------------------------- 1 | % insert_data_BENZ_ISOPRO 2 | % x0=[10 10]; 3 | % x0=[-664.517622649858,448.908713462131,905.340942693372,1508.60606346376,-100.646994812078,-295.820691775821]; 4 | 5 | %ff=@(du) 1/FIT_function_flex(du,components) 6 | ff=@(du) 1/FIT_function_flexTP(du,components); 7 | %% 8 | % ff= @(du) gammacalc(du(1),du(2),du(3),du(4),du(5),du(6)) 9 | % ff=@(x)1/petama(x(1),x(2),x(3),x(4),x(5),x(6)); 10 | % f=@(x)1/Fit_functionT(x(1),x(2)); du0=[-173.3*R 204.5*R 88.33*R 669.96*R 11 | % -43.9*R -132.6*R]; du0=[-316.76*R 228.16*R 383.21*R 692.77*R -51.92*R 12 | % -141.75*R]; zsxq1000=[-316.30*R 227.93*R 381.65*R 699.42*R -51.88*R 13 | % -142.00*R]; 14 | %dd6=[-628.554523000000,452.944775300000,758.418696500000,1389.89441820000,-103.096454800000,-282.183820000000] 15 | %dd12=[263.90 668.50 63.07 -18.05 111.40 -327.48 388.05 172.09 -290.26 148.28 469.57 460.57] 16 | % du0=[1000 1000 1000 1000 1000 1000]; 17 | % orio=1000; 18 | % for k=1:12 19 | % du0(1,k) = round(rand*(orio*2)-orio); 20 | % end% create a table 6xpop_size (6 du per solution) 21 | % %% 22 | % du0=ones(1,12)*10000/7; 23 | % load('output6x200.mat') 24 | load('option_clas_solver.mat'); 25 | load('optionfminimax.mat') 26 | lsqnonlin_results=[]; 27 | fminsearch_results=[]; 28 | fminimax_results=[]; 29 | iv=1; 30 | for i=1:1000 %create the first score data 31 | for k=1:12 32 | gen_1_Duvalues(k,i) = round(rand*(Dumax-Dumin)+Dumin); 33 | end% create a table 6xpop_size (6 du per solution) 34 | 35 | end 36 | while iv <= 10000 37 | du0(:)=gen_1_Duvalues(:,iv); 38 | 39 | tic 40 | du=[]; 41 | 42 | [du,resnorm,resixal,exitflag,output] = lsqnonlin(ff,du0,[],[],options); 43 | lsqnonlin_results(iv,1:12)=du(:);lsqnonlin_results(iv,13)=1/resixal;lsqnonlin_results(iv,14)=toc; 44 | % lsqnonlin_results=sortrows(lsqnonlin_results,7); 45 | %% 46 | 47 | tic 48 | du=[]; 49 | [du,fval] = myfminsearch(ff,du0,2000,2000) 50 | fminsearch_results(iv,1:12)=du(:);fminsearch_results(iv,13)=1/fval;fminsearch_results(iv,14)=toc; 51 | %fminsearch_results=sortrows(fminsearch_results,7); 52 | 53 | %% 54 | dumin=[]; 55 | tic 56 | try 57 | [dumin,fval2] = fminimax(ff,du0,[],[],[],[],[],[],[],optionsfminimax); 58 | fminimax_results(iv,1:12)=dumin(:);fminimax_results(iv,13)=1/fval2;fminimax_results(iv,14)=toc; 59 | % fminimax_results=sortrows(fminimax_results,7); 60 | end 61 | % % du/R 62 | % %petama(x(1),x(2),x(3),x(4),x(5),x(6)) 63 | % Fit_function_TERN(du(1),du(2),du(3),du(4),du(5),du(6)) 64 | % du0=du; 65 | iv=iv+1 66 | end 67 | % du0 68 | % sol=[1/resixal 1/fval 1/fval2] 69 | 70 | 71 | %% check results for succesfull ones 72 | 73 | % lsqnonlin_resultsSUCCES= sum(sum(lsqnonlin_results(:,13)> 14.86)) 74 | % fminsearch_resultsSUCCESS= sum(sum(fminsearch_results(:,13)> 14.86)) 75 | % fminimax_resultsSUCCESS=sum(sum(fminimax_results(:,13)> 14.86)) 76 | 77 | orio=5; 78 | lsqnonlin_resultsSUCCES= sum(sum(lsqnonlin_results(:,13)>orio)); 79 | fminsearch_resultsSUCCESS= sum(sum(fminsearch_results(:,13)> orio)); 80 | fminimax_resultsSUCCESS=sum(sum(fminimax_results(:,13)> orio)); 81 | % 82 | FINAL_SUCCES=[lsqnonlin_resultsSUCCES fminsearch_resultsSUCCESS fminimax_resultsSUCCESS] 83 | % summary(T) 84 | %[x,fval] = fminunc(ff,du0);1/fval 85 | %[x,fval] = fminsearch(ff,du0); 1/fval 86 | %1/fval 87 | %du=du0; 88 | % options.Algorithm = 'levenberg-marquardt'; 89 | % [x,resnorm,resixal,exitflag,output] = lsqnonlin(ff,x0,[],[],options); 90 | 91 | -------------------------------------------------------------------------------- /classicsolver[Conflict].m: -------------------------------------------------------------------------------- 1 | % insert_data_BENZ_ISOPRO 2 | % x0=[10 10]; 3 | % x0=[-664.517622649858,448.908713462131,905.340942693372,1508.60606346376,-100.646994812078,-295.820691775821]; 4 | 5 | %ff=@(du) 1/FIT_function_flex(du,components) 6 | ff=@(du) 1/FIT_function_flexTP(du,components); 7 | %% 8 | % ff= @(du) gammacalc(du(1),du(2),du(3),du(4),du(5),du(6)) 9 | % ff=@(x)1/petama(x(1),x(2),x(3),x(4),x(5),x(6)); 10 | % f=@(x)1/Fit_functionT(x(1),x(2)); du0=[-173.3*R 204.5*R 88.33*R 669.96*R 11 | % -43.9*R -132.6*R]; du0=[-316.76*R 228.16*R 383.21*R 692.77*R -51.92*R 12 | % -141.75*R]; zsxq1000=[-316.30*R 227.93*R 381.65*R 699.42*R -51.88*R 13 | % -142.00*R]; 14 | %dd6=[-628.554523000000,452.944775300000,758.418696500000,1389.89441820000,-103.096454800000,-282.183820000000] 15 | %dd12=[263.90 668.50 63.07 -18.05 111.40 -327.48 388.05 172.09 -290.26 148.28 469.57 460.57] 16 | % du0=[1000 1000 1000 1000 1000 1000]; 17 | for k=1:du_number 18 | du0(1,k) = round(rand*(Dumax-Dumin)+Dumin); 19 | end% create a table 6xpop_size (6 du per solution) 20 | %% 21 | % load('output6x200.mat') 22 | load('option_clas_solver.mat'); 23 | load('optionfminimax.mat') 24 | lsqnonlin_results=[]; 25 | fminsearch_results=[]; 26 | fminimax_results=[]; 27 | iv=1; 28 | % for i=1:1000000 %create the first score data 29 | % for k=1:12 30 | % gen_1_Duvalues(k,i) = round(rand*(Dumax-Dumin)+Dumin); 31 | % end% create a table 6xpop_size (6 du per solution) 32 | % 33 | % end 34 | while iv <= 10000 35 | du0(:)=gen_1_Duvalues(:,iv); 36 | 37 | tic 38 | du=[]; 39 | 40 | [du,resnorm,resixal,exitflag,output] = lsqnonlin(ff,du0,[],[],options); 41 | lsqnonlin_results(iv,1:12)=du(:);lsqnonlin_results(iv,13)=1/resixal;lsqnonlin_results(iv,14)=toc; 42 | % lsqnonlin_results=sortrows(lsqnonlin_results,7); 43 | %% 44 | 45 | tic 46 | du=[];du 47 | [du,fval] = myfminsearch(ff,du0,2000,2000) 48 | fminsearch_results(iv,1:12)=du(:);fminsearch_results(iv,13)=1/fval;fminsearch_results(iv,14)=toc; 49 | %fminsearch_results=sortrows(fminsearch_results,7); 50 | 51 | %% 52 | dumin=[]; 53 | tic 54 | try 55 | [dumin,fval2] = fminimax(ff,du0,[],[],[],[],[],[],[],optionsfminimax); 56 | fminimax_results(iv,1:12)=dumin(:);fminimax_results(iv,13)=1/fval2;fminimax_results(iv,14)=toc; 57 | % fminimax_results=sortrows(fminimax_results,7); 58 | end 59 | % % du/R 60 | % %petama(x(1),x(2),x(3),x(4),x(5),x(6)) 61 | % Fit_function_TERN(du(1),du(2),du(3),du(4),du(5),du(6)) 62 | % du0=du; 63 | iv=iv+1 64 | end 65 | 66 | sol=[1/resixal 1/fval 1/fval2] 67 | 68 | 69 | %% check results for succesfull ones 70 | 71 | % lsqnonlin_resultsSUCCES= sum(sum(lsqnonlin_results(:,13)> 14.86)) 72 | % fminsearch_resultsSUCCESS= sum(sum(fminsearch_results(:,13)> 14.86)) 73 | % fminimax_resultsSUCCESS=sum(sum(fminimax_results(:,13)> 14.86)) 74 | 75 | orio=2.5; 76 | lsqnonlin_resultsSUCCES= sum(sum(lsqnonlin_results(:,13)>orio)) 77 | fminsearch_resultsSUCCESS= sum(sum(fminsearch_results(:,13)> orio)) 78 | fminimax_resultsSUCCESS=sum(sum(fminimax_results(:,13)> orio)) 79 | 80 | FINAL_SUCCES=[lsqnonlin_resultsSUCCES fminsearch_resultsSUCCESS fminimax_resultsSUCCESS] 81 | summary(T) 82 | %[x,fval] = fminunc(ff,du0);1/fval 83 | %[x,fval] = fminsearch(ff,du0); 1/fval 84 | %1/fval 85 | %du=du0; 86 | % options.Algorithm = 'levenberg-marquardt'; 87 | % [x,resnorm,resixal,exitflag,output] = lsqnonlin(ff,x0,[],[],options); 88 | 89 | -------------------------------------------------------------------------------- /compare2.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pngts/Nonlinear-parameter-estimation-in-thermodynamic-models/93bd1a062f616e61b0d7214b293b14d48dd16c81/compare2.xlsx -------------------------------------------------------------------------------- /comparison_auto_save.m: -------------------------------------------------------------------------------- 1 | insert_data_exp_TERNset2_150 2 | sheet=0; 3 | while sheet<5 4 | %ga_test4b_TERN 5 | ga_test4b_TERN_STOP1 6 | sheet=sheet+1 7 | filename = 'comparison_AUTOSAVE2_stop_150.xlsx'; 8 | 9 | xlRange1 = 'A1'; 10 | BB(:)=All_generations_RESULTS(length(All_generations_RESULTS),:); 11 | xlswrite(filename,BB,sheet,xlRange1) 12 | 13 | load('outputB_stop_6x200.mat') 14 | 15 | classicsolver 16 | xlRange3 = 'A10:H207'; 17 | xlswrite(filename,lsqnonlin_results,sheet,xlRange3) 18 | 19 | xlRange4 = 'J10:S207'; 20 | xlswrite(filename,fminsearch_results,sheet,xlRange4) 21 | 22 | xlRange5 = 'U10:AD207'; 23 | xlswrite(filename,fminimax_results,sheet,xlRange5) 24 | 25 | xlRange2 = 'A2:GS7'; 26 | load('outputB_stop_6x200.mat') 27 | xlswrite(filename,gen_1_Duvalues,sheet,xlRange2) 28 | 29 | end -------------------------------------------------------------------------------- /dokimes_gaTERN.m: -------------------------------------------------------------------------------- 1 | % %% ================================================================================ 2 | % insert_data_exp_TERNset2_150 3 | % NO_exp=5;%arithmos piramaton 4 | % All_generations_RESULTS=[]; 5 | % kp=1; 6 | % ga_test4b_TERN 7 | % runResultspopsize=[]; 8 | % while kp 42 | end 43 | 44 | %% Allocate imported array to column variable names 45 | TK = data(:,1); 46 | Pmmhg = data(:,2); 47 | X1 = data(:,3); 48 | X2 = data(:,4); 49 | X3 = data(:,5); 50 | Y1 = data(:,6); 51 | Y2 = data(:,7); 52 | Y3 = data(:,8); 53 | gamma_exp1 = data(:,9); 54 | gamma_exp2 = data(:,10); 55 | gamma_exp3 = data(:,11); 56 | gamma_exp4 = data(:,12); 57 | 58 | -------------------------------------------------------------------------------- /importfileTERN_excel.m: -------------------------------------------------------------------------------- 1 | function [TK,PmmHg,X1,X2,Y1,Y2] = importfileTERN_excel(workbookFile,sheetName,startRow,endRow) 2 | %IMPORTFILE2 Import data from a spreadsheet 3 | % [TK,PmmHg,X1,X2,Y1,Y2] = IMPORTFILE2(FILE) reads data from the first 4 | % worksheet in the Microsoft Excel spreadsheet file named FILE and 5 | % returns the data as column vectors. 6 | % 7 | % [TK,PmmHg,X1,X2,Y1,Y2] = IMPORTFILE2(FILE,SHEET) reads from the 8 | % specified worksheet. 9 | % 10 | % [TK,PmmHg,X1,X2,Y1,Y2] = IMPORTFILE2(FILE,SHEET,STARTROW,ENDROW) reads 11 | % from the specified worksheet for the specified row interval(s). Specify 12 | % STARTROW and ENDROW as a pair of scalars or vectors of matching size 13 | % for dis-contiguous row intervals. To read to the end of the file 14 | % specify an ENDROW of inf.% 15 | % Example: 16 | % [TK,PmmHg,X1,X2,Y1,Y2] = 17 | % importfile2('Acet-CHCl3-meth2.xlsx','Acet-CHCl3-meth2',6,41); 18 | % 19 | % See also XLSREAD. 20 | 21 | % Auto-generated by MATLAB on 2017/10/23 01:28:46 22 | 23 | %% Input handling 24 | 25 | % If no sheet is specified, read first sheet 26 | if nargin == 1 || isempty(sheetName) 27 | sheetName = 1; 28 | end 29 | 30 | % If row start and end points are not specified, define defaults 31 | if nargin <= 3 32 | startRow = 6; 33 | endRow = 41; 34 | end 35 | 36 | %% Import the data 37 | data = xlsread(workbookFile, sheetName, sprintf('A%d:F%d',startRow(1),endRow(1))); 38 | for block=2:length(startRow) 39 | tmpDataBlock = xlsread(workbookFile, sheetName, sprintf('A%d:F%d',startRow(block),endRow(block))); 40 | data = [data;tmpDataBlock]; %#ok 41 | end 42 | 43 | %% Allocate imported array to column variable names 44 | TK = data(:,1); 45 | PmmHg = data(:,2); 46 | X1 = data(:,3); 47 | X2 = data(:,4); 48 | Y1 = data(:,5); 49 | Y2 = data(:,6); 50 | 51 | -------------------------------------------------------------------------------- /importfile_EXCEL.m: -------------------------------------------------------------------------------- 1 | function [TK1,PmmHg,X1,Y1] = importfile_EXCEL(workbookFile,sheetName,startRow,endRow) 2 | %IMPORTFILE2 Import data from a spreadsheet 3 | % [TK1,PmmHg,X1,Y1] = IMPORTFILE2(FILE) reads data from the first 4 | % worksheet in the Microsoft Excel spreadsheet file named FILE and 5 | % returns the data as column vectors. 6 | % 7 | % [TK1,PmmHg,X1,Y1] = IMPORTFILE2(FILE,SHEET) reads from the specified 8 | % worksheet. 9 | % 10 | % [TK1,PmmHg,X1,Y1] = IMPORTFILE2(FILE,SHEET,STARTROW,ENDROW) reads from 11 | % the specified worksheet for the specified row interval(s). Specify 12 | % STARTROW and ENDROW as a pair of scalars or vectors of matching size 13 | % for dis-contiguous row intervals. To read to the end of the file 14 | % specify an ENDROW of inf.% 15 | % Example: 16 | % [TK1,PmmHg,X1,Y1] = importfile2('ACET-CHCL3.xlsx','Sheet1',3,35); 17 | % 18 | % See also XLSREAD. 19 | 20 | % Auto-generated by MATLAB on 2017/10/20 01:44:24 21 | 22 | %% Input handling 23 | 24 | % If no sheet is specified, read first sheet 25 | if nargin == 1 || isempty(sheetName) 26 | sheetName = 1; 27 | end 28 | 29 | % If row start and end points are not specified, define defaults 30 | if nargin <= 3 31 | startRow = 3; 32 | endRow = 35; 33 | end 34 | 35 | %% Import the data 36 | data = xlsread(workbookFile, sheetName, sprintf('A%d:D%d',startRow(1),endRow(1))); 37 | for block=2:length(startRow) 38 | tmpDataBlock = xlsread(workbookFile, sheetName, sprintf('A%d:D%d',startRow(block),endRow(block))); 39 | data = [data;tmpDataBlock]; %#ok 40 | end 41 | 42 | %% Allocate imported array to column variable names 43 | TK1 = data(:,1); 44 | PmmHg = data(:,2); 45 | X1 = data(:,3); 46 | Y1 = data(:,4); 47 | 48 | -------------------------------------------------------------------------------- /importfile_QUAD_EXCEL.m: -------------------------------------------------------------------------------- 1 | function [TK1,Pmmhg,X1,X2,X3,Y1,Y2,Y3] = importfile_QUAD_EXCEL(workbookFile,sheetName,startRow,endRow) 2 | %IMPORTFILE2 Import data from a spreadsheet 3 | % [TK1,Pmmhg,X1,X2,X3,Y1,Y2,Y3] = IMPORTFILE2(FILE) reads data from the 4 | % first worksheet in the Microsoft Excel spreadsheet file named FILE and 5 | % returns the data as column vectors. 6 | % 7 | % [TK1,Pmmhg,X1,X2,X3,Y1,Y2,Y3] = IMPORTFILE2(FILE,SHEET) reads from the 8 | % specified worksheet. 9 | % 10 | % [TK1,Pmmhg,X1,X2,X3,Y1,Y2,Y3] = IMPORTFILE2(FILE,SHEET,STARTROW,ENDROW) 11 | % reads from the specified worksheet for the specified row interval(s). 12 | % Specify STARTROW and ENDROW as a pair of scalars or vectors of matching 13 | % size for dis-contiguous row intervals. To read to the end of the file 14 | % specify an ENDROW of inf. 15 | % 16 | % Non-numeric cells are replaced with: NaN 17 | % 18 | % Example: 19 | % [TK1,Pmmhg,X1,X2,X3,Y1,Y2,Y3] = importfile2('quaternary1.xlsx','Sheet1',4,37); 20 | % 21 | % See also XLSREAD. 22 | 23 | % Auto-generated by MATLAB on 2018/03/13 21:48:03 24 | 25 | %% Input handling 26 | 27 | % If no sheet is specified, read first sheet 28 | if nargin == 1 || isempty(sheetName) 29 | sheetName = 1; 30 | end 31 | 32 | % If row start and end points are not specified, define defaults 33 | if nargin <= 3 34 | startRow = 4; 35 | endRow = 37; 36 | end 37 | 38 | %% Import the data 39 | [~, ~, raw] = xlsread(workbookFile, sheetName, sprintf('A%d:H%d',startRow(1),endRow(1))); 40 | for block=2:length(startRow) 41 | [~, ~, tmpRawBlock] = xlsread(workbookFile, sheetName, sprintf('A%d:H%d',startRow(block),endRow(block))); 42 | raw = [raw;tmpRawBlock]; %#ok 43 | end 44 | raw(cellfun(@(x) ~isempty(x) && isnumeric(x) && isnan(x),raw)) = {''}; 45 | 46 | %% Replace non-numeric cells with NaN 47 | R = cellfun(@(x) ~isnumeric(x) && ~islogical(x),raw); % Find non-numeric cells 48 | raw(R) = {NaN}; % Replace non-numeric cells 49 | 50 | %% Create output variable 51 | I = cellfun(@(x) ischar(x), raw); 52 | raw(I) = {NaN}; 53 | data = reshape([raw{:}],size(raw)); 54 | 55 | %% Allocate imported array to column variable names 56 | TK1 = data(:,1); 57 | Pmmhg = data(:,2); 58 | X1 = data(:,3); 59 | X2 = data(:,4); 60 | X3 = data(:,5); 61 | Y1 = data(:,6); 62 | Y2 = data(:,7); 63 | Y3 = data(:,8); 64 | 65 | -------------------------------------------------------------------------------- /insert_TERN_TP.m: -------------------------------------------------------------------------------- 1 | clc;clear 2 | format long 3 | global TK R gamma_exp X r q q1 gamma_cal Y 4 | %% eisagogi dedomenwn 5 | components=3; 6 | [TK,Pbar,Y1,X1,Y2,X2] = importfile1('TERNARY_revised.DAT',3, 41); 7 | % AntoineTableBrowse.m emfanizei tis statheres antoine 8 | id = [37 63 44]; % antoiine id 9 | % TK=TK(1); % metrisis stin idia T 10 | T=TK-273.15; % se c 11 | [names A B C] = AntoineGet(id); 12 | Ps = 10.^(A - B./(T+C)); % DINEI mmHg kai c 13 | Ps=0.0013332239*Ps ; % metatropi se bar 14 | %% ipologismos piramatikwn gamma 15 | gamma_exp=[]; 16 | X3 = 1-X1-X2; Y3=1-Y1-Y2; % calculate x3 17 | X = [X1 X2 X3]; Y=[Y1 Y2 Y3]; % create column array of x1 & x2 & X3 18 | for i=1:length( X1 ) 19 | for k=1:3 20 | gamma_exp(i,k)=Y(i,k).*Pbar(i)./(X(i,k).*Ps(i,k)); 21 | end 22 | end 23 | gamma_exp; 24 | %% isagogi statherwn uniquac gia to dedomeno migma 25 | R=1.9872; 26 | r=[2.5735 1.4311 0.92]; 27 | q=[2.3360 1.432 1.4] ;q1=q; 28 | gamma_cal=[]; 29 | %---------------------- 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /insert_data_BENZ_ISOPRO_T.m: -------------------------------------------------------------------------------- 1 | clc;clear 2 | % format long 3 | global TK R gamma_exp X r q q1 gamma_cal 4 | %% eisagogi dedomenwn 5 | components=2; 6 | [TK,PmmHg,X1,Y1] = importfile_EXCEL('benz_propylAlcho','Sheet1',3,16); % orizoume kai apo pou mexri pou na diavasi 7 | id = [64 65]; % antoiine id 8 | % TK=TK1(1); % metrisis stin idia T 9 | T=TK-273.15; % se c 10 | [names A B C] = AntoineGet(id); 11 | for j=1:2 12 | for i=1:length( X1 ) 13 | Ps(i,j) = exp((A(j) - B(j)/(TK(i)+C(j)))); % DINEI mmHg kai K 14 | end 15 | end 16 | %Ps=0.0013332239*Ps ; % metatropi se bar 17 | %% ipologismos piramatikwn gamma 18 | gamma_exp=[]; 19 | X2 = 1-X1; % calculate x2 20 | X = [X1 X2]; % create a 2 column array of x1 & x2 21 | for i=1:length( X1 ) 22 | gamma_exp(i,1)=Y1(i).*PmmHg(i)./(X1(i).*Ps(i,1)); 23 | gamma_exp(i,2)=(1-Y1(i)).*PmmHg(i)./(X2(i).*Ps(i,2)); 24 | end 25 | gamma_exp; 26 | %% isagogi statherwn uniquac gia to dedomeno migma 27 | R=1.9872; 28 | r=[3.1878 2.7791]; 29 | q=[2.40 2.508] ;q1=q; 30 | gamma_cal=[]; 31 | %---------------------- 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /insert_data__acetone_meth.m: -------------------------------------------------------------------------------- 1 | clc;clear 2 | % format long 3 | global TK R gamma_exp X r q q1 gamma_cal 4 | %% eisagogi dedomenwn 5 | components=2; 6 | [TK,Pbar,Y1,X1] = importfile('ACET-1OL.DAT',3, 16); 7 | id = [36 61]; % antoiine id 8 | TK=TK(1); % metrisis stin idia T 9 | T=TK(1)-273.15; % se c 10 | [names A B C] = AntoineGet(id); 11 | Ps = 10.^(A - B./(T+C)); % DINEI mmHg kai c 12 | Ps=0.0013332239*Ps ; % metatropi se bar 13 | %% ipologismos piramatikwn gamma 14 | gamma_exp=[]; 15 | X2 = 1-X1; % calculate x2 16 | X = [X1 X2]; % create a 2 column array of x1 & x2 17 | for i=1:length( X1 ) 18 | gamma_exp(i,1)=Y1(i).*Pbar(i)./(X1(i).*Ps(1)); 19 | gamma_exp(i,2)=(1-Y1(i)).*Pbar(i)./(X2(i).*Ps(2)); 20 | end 21 | gamma_exp; 22 | %% isagogi statherwn uniquac gia to dedomeno migma 23 | R=1.9872; 24 | r=[2.5735 1.4311]; 25 | q=[2.336 1.432] ;q1=q; 26 | gamma_cal=[]; 27 | %---------------------- 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /insert_data__acetone_meth2.m: -------------------------------------------------------------------------------- 1 | clc;clear 2 | % format long 3 | global TK R gamma_exp X r q q1 gamma_cal 4 | %% eisagogi dedomenwn 5 | components=2; 6 | [TK1,PmmHg,X1,Y1] = importfile_EXCEL('METH-ACET.xlsx','Sheet1',3,30); % orizoume kai apo pou mexri pou na diavasi 7 | id = [37 2]; % antoiine id 8 | TK=TK1(1); % metrisis stin idia T 9 | T=TK-273.15; % se c 10 | [names A B C] = AntoineGet(id); 11 | Ps = 10.^(A - B./(T+C)); % DINEI mmHg kai c 12 | %Ps=0.0013332239*Ps ; % metatropi se bar 13 | %% ipologismos piramatikwn gamma 14 | gamma_exp=[]; 15 | X2 = 1-X1; % calculate x2 16 | X = [X1 X2]; % create a 2 column array of x1 & x2 17 | for i=1:length( X1 ) 18 | gamma_exp(i,1)=Y1(i).*PmmHg(i)./(X1(i).*Ps(1)); 19 | gamma_exp(i,2)=(1-Y1(i)).*PmmHg(i)./(X2(i).*Ps(2)); 20 | end 21 | gamma_exp; 22 | %% isagogi statherwn uniquac gia to dedomeno migma 23 | R=1.9872; 24 | r=[2.5735 1.4311]; 25 | q=[2.3360 1.4320] ;q1=q; 26 | gamma_cal=[]; 27 | %---------------------- 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /insert_data__acetone_meth2_TP.m: -------------------------------------------------------------------------------- 1 | clc;clear 2 | % format long 3 | global TK R gamma_exp X r q q1 gamma_cal 4 | %% eisagogi dedomenwn 5 | components=2; 6 | [TK,PmmHg,X1,Y1] = importfile_EXCEL('METH-ACET.xlsx','Sheet1',3,30); % orizoume kai apo pou mexri pou na diavasi 7 | id = [37 2]; % antoiine id ---> load('AntoineTable.mat') 8 | %TK=TK1(1); % metrisis stin idia T 9 | T=TK-273.15; % se c 10 | [names A B C] = AntoineGet(id); 11 | Ps = 10.^(A - B./(T+C)); % DINEI mmHg kai c 12 | %Ps=0.0013332239*Ps ; % metatropi se bar 13 | %% ipologismos piramatikwn gamma 14 | gamma_exp=[]; 15 | X2 = 1-X1; % calculate x2 16 | X = [X1 X2]; % create a 2 column array of x1 & x2 17 | for i=1:length( X1 ) 18 | gamma_exp(i,1)=Y1(i).*PmmHg(i)./(X1(i).*Ps(i,1)); 19 | gamma_exp(i,2)=(1-Y1(i)).*PmmHg(i)./(X2(i).*Ps(i,2)); 20 | end 21 | gamma_exp; 22 | %% isagogi statherwn uniquac gia to dedomeno migma 23 | R=1.9872; 24 | r=[2.5735 1.4311]; 25 | q=[2.3360 1.4320] ;q1=q; 26 | gamma_cal=[]; 27 | %---------------------- 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /insert_data__acetone_meth_TP.m: -------------------------------------------------------------------------------- 1 | clc;clear 2 | % format long 3 | global TK R gamma_exp X r q q1 gamma_cal 4 | %% eisagogi dedomenwn 5 | components=2; 6 | [TK,Pbar,Y1,X1] = importfile('ACET-1OL.DAT',3, 16); 7 | id = [36 61]; % antoiine id ---> load('AntoineTable.mat') 8 | %TK=TK(1); % metrisis stin idia T 9 | T=TK-273.15; % se c 10 | [names A B C] = AntoineGet(id); 11 | Ps = 10.^(A - B./(T+C)); % DINEI mmHg kai c 12 | Ps=0.0013332239*Ps ; % metatropi se bar 13 | %% ipologismos piramatikwn gamma 14 | gamma_exp=[]; 15 | X2 = 1-X1; % calculate x2 16 | X = [X1 X2]; % create a 2 column array of x1 & x2 17 | for i=1:length( X1 ) 18 | gamma_exp(i,1)=Y1(i).*Pbar(i)./(X1(i).*Ps(i,1)); 19 | gamma_exp(i,2)=(1-Y1(i)).*Pbar(i)./(X2(i).*Ps(i,2)); 20 | end 21 | gamma_exp; 22 | %% isagogi statherwn uniquac gia to dedomeno migma 23 | R=1.9872; 24 | r=[2.5735 1.4311]; 25 | q=[2.336 1.432] ;q1=q; 26 | gamma_cal=[]; 27 | %---------------------- 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /insert_data_acet_chcl3.m: -------------------------------------------------------------------------------- 1 | clc;clear 2 | % format long 3 | global TK R gamma_exp X r q q1 gamma_cal 4 | %% eisagogi dedomenwn 5 | components=2; 6 | [TK1,PmmHg,X1,Y1] = importfile_EXCEL('ACET-CHCL3.xlsx','Sheet1',3,33); % orizoume kai apo pou mexri pou na diavasi 7 | id = [37 49]; % antoiine id 8 | TK=TK1(1); % metrisis stin idia T 9 | T=TK(1)-273.15; % se c 10 | [names A B C] = AntoineGet(id); 11 | Ps = 10.^(A - B./(T+C)); % DINEI mmHg kai c 12 | %Ps=0.0013332239*Ps ; % metatropi se bar 13 | %% ipologismos piramatikwn gamma 14 | gamma_exp=[]; 15 | X2 = 1-X1; % calculate x2 16 | X = [X1 X2]; % create a 2 column array of x1 & x2 17 | for i=1:length( X1 ) 18 | gamma_exp(i,1)=Y1(i).*PmmHg(i)./(X1(i).*Ps(1)); 19 | gamma_exp(i,2)=(1-Y1(i)).*PmmHg(i)./(X2(i).*Ps(2)); 20 | end 21 | gamma_exp; 22 | %% isagogi statherwn uniquac gia to dedomeno migma 23 | R=1.9872; 24 | r=[2.5735 2.37]; 25 | q=[2.3360 2.41] ;q1=q; 26 | gamma_cal=[]; 27 | %---------------------- 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /insert_data_acet_chcl3_TP.m: -------------------------------------------------------------------------------- 1 | clc;clear 2 | % format long 3 | global TK R gamma_exp X r q q1 gamma_cal 4 | %% eisagogi dedomenwn 5 | components=2; 6 | [TK,PmmHg,X1,Y1] = importfile_EXCEL('ACET-CHCL3.xlsx','Sheet1',3,33); % orizoume kai apo pou mexri pou na diavasi 7 | id = [37 49]; % antoiine id ---> load('AntoineTable.mat') 8 | %TK=TK1(1); % metrisis stin idia T 9 | T=TK-273.15; % se c 10 | [names A B C] = AntoineGet(id); 11 | Ps = 10.^(A - B./(T+C)); % DINEI mmHg kai c 12 | %Ps=0.0013332239*Ps ; % metatropi se bar 13 | %% ipologismos piramatikwn gamma 14 | gamma_exp=[]; 15 | X2 = 1-X1; % calculate x2 16 | X = [X1 X2]; % create a 2 column array of x1 & x2 17 | for i=1:length( X1 ) 18 | gamma_exp(i,1)=Y1(i).*PmmHg(i)./(X1(i).*Ps(i,1)); 19 | gamma_exp(i,2)=(1-Y1(i)).*PmmHg(i)./(X2(i).*Ps(i,2)); 20 | end 21 | gamma_exp; 22 | %% isagogi statherwn uniquac gia to dedomeno migma 23 | R=1.9872; 24 | r=[2.5735 2.37]; 25 | q=[2.3360 2.41] ;q1=q; 26 | gamma_cal=[]; 27 | %---------------------- 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /insert_data_acetone_water.m: -------------------------------------------------------------------------------- 1 | clc;clear 2 | % format long 3 | global TK R gamma_exp X r q q1 gamma_cal 4 | %% eisagogi dedomenwn 5 | components=2; 6 | [TK,Pbar,Y1,X1] = importfile('ACET-H2O.DAT',3, 24); 7 | id = [37 44]; % antoiine id 8 | TK=TK(1); % metrisis stin idia T 9 | T=TK(1)-273.15; % se c 10 | [names A B C] = AntoineGet(id); 11 | Ps = 10.^(A - B./(T+C)); % DINEI mmHg kai c 12 | Ps=0.0013332239*Ps ; % metatropi se bar 13 | %% ipologismos piramatikwn gamma 14 | gamma_exp=[]; 15 | X2 = 1-X1; % calculate x2 16 | X = [X1 X2]; % create a 2 column array of x1 & x2 17 | for i=1:length( X1 ) 18 | gamma_exp(i,1)=Y1(i).*Pbar(i)./(X1(i).*Ps(1)); 19 | gamma_exp(i,2)=(1-Y1(i)).*Pbar(i)./(X2(i).*Ps(2)); 20 | end 21 | gamma_exp; 22 | %% isagogi statherwn uniquac gia to dedomeno migma 23 | R=1.9872; 24 | r=[2.5735 0.92]; 25 | q=[2.336 1.4] ;q1=q; 26 | gamma_cal=[]; 27 | %---------------------- 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /insert_data_acetone_water_TP.m: -------------------------------------------------------------------------------- 1 | clc;clear 2 | % format long 3 | global TK R gamma_exp X r q q1 gamma_cal 4 | %% eisagogi dedomenwn 5 | components=2; 6 | [TK,Pbar,Y1,X1] = importfile('ACET-H2O.DAT',3, 24); 7 | id = [37 44]; % antoiine id ---> load('AntoineTable.mat') 8 | % TK=TK(1); % metrisis stin idia T 9 | T=TK-273.15; % se c 10 | [names A B C] = AntoineGet(id); 11 | Ps = 10.^(A - B./(T+C)); % DINEI mmHg kai c 12 | Ps=0.0013332239*Ps ; % metatropi se bar 13 | %% ipologismos piramatikwn gamma 14 | gamma_exp=[]; 15 | X2 = 1-X1; % calculate x2 16 | X = [X1 X2]; % create a 2 column array of x1 & x2 17 | for i=1:length( X1 ) 18 | gamma_exp(i,1)=Y1(i).*Pbar(i)./(X1(i).*Ps(i,1)); 19 | gamma_exp(i,2)=(1-Y1(i)).*Pbar(i)./(X2(i).*Ps(i,2)); 20 | end 21 | gamma_exp; 22 | %% isagogi statherwn uniquac gia to dedomeno migma 23 | R=1.9872; 24 | r=[2.5735 0.92]; 25 | q=[2.336 1.4] ;q1=q; 26 | gamma_cal=[]; 27 | %---------------------- 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /insert_data_chcl3_meth.m: -------------------------------------------------------------------------------- 1 | clc;clear 2 | % format long 3 | global TK R gamma_exp X r q q1 gamma_cal 4 | %% eisagogi dedomenwn 5 | components=2; 6 | [TK1,PmmHg,X1,Y1] = importfile_EXCEL('CHCL3-METH.xlsx','Sheet1',3,21); % orizoume kai apo pou mexri pou na diavasi 7 | id = [49 2]; % antoiine id 8 | TK=TK1(1); % metrisis stin idia T 9 | T=TK(1)-273.15; % se c 10 | [names A B C] = AntoineGet(id); 11 | Ps = 10.^(A - B./(T+C)); % DINEI mmHg kai c 12 | %Ps=0.0013332239*Ps ; % metatropi se bar 13 | %% ipologismos piramatikwn gamma 14 | gamma_exp=[]; 15 | X2 = 1-X1; % calculate x2 16 | X = [X1 X2]; % create a 2 column array of x1 & x2 17 | for i=1:length( X1 ) 18 | gamma_exp(i,1)=Y1(i).*PmmHg(i)./(X1(i).*Ps(1)); 19 | gamma_exp(i,2)=(1-Y1(i)).*PmmHg(i)./(X2(i).*Ps(2)); 20 | end 21 | gamma_exp; 22 | %% isagogi statherwn uniquac gia to dedomeno migma 23 | R=1.9872; 24 | r=[2.37 1.4311]; 25 | q=[2.41 1.4320] ;q1=q; 26 | gamma_cal=[]; 27 | %---------------------- 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /insert_data_chcl3_meth_TP.m: -------------------------------------------------------------------------------- 1 | clc;clear 2 | % format long 3 | global TK R gamma_exp X r q q1 gamma_cal 4 | %% eisagogi dedomenwn 5 | components=2; 6 | [TK,PmmHg,X1,Y1] = importfile_EXCEL('CHCL3-METH.xlsx','Sheet1',3,21); % orizoume kai apo pou mexri pou na diavasi 7 | id = [49 2]; % antoiine id ---> load('AntoineTable.mat') 8 | %TK=TK1(1); % metrisis stin idia T 9 | T=TK-273.15; % se c 10 | [names A B C] = AntoineGet(id); 11 | Ps = 10.^(A - B./(T+C)); % DINEI mmHg kai c 12 | %Ps=0.0013332239*Ps ; % metatropi se bar 13 | %% ipologismos piramatikwn gamma 14 | gamma_exp=[]; 15 | X2 = 1-X1; % calculate x2 16 | X = [X1 X2]; % create a 2 column array of x1 & x2 17 | for i=1:length( X1 ) 18 | gamma_exp(i,1)=Y1(i).*PmmHg(i)./(X1(i).*Ps(i,1)); 19 | gamma_exp(i,2)=(1-Y1(i)).*PmmHg(i)./(X2(i).*Ps(i,2)); 20 | end 21 | gamma_exp; 22 | %% isagogi statherwn uniquac gia to dedomeno migma 23 | R=1.9872; 24 | r=[2.37 1.4311]; 25 | q=[2.41 1.4320] ;q1=q; 26 | gamma_cal=[]; 27 | %---------------------- 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /insert_data_exp_TERNSET2_150_TP.m: -------------------------------------------------------------------------------- 1 | clc;clear 2 | format long 3 | global TK R gamma_exp X r q q1 gamma_cal Y 4 | %% eisagogi dedomenwn 5 | components=3; 6 | [TK,Pbar,X1,X2,Y1,Y2] = importfileTERN_excel('Acet-CHCl3-meth150.xlsx','Acet-CHCl3-meth2',6,155); 7 | id = [37 49 2]; % antoiine id ---> load('AntoineTable.mat') 8 | % TK=TK(1); % metrisis stin idia T 9 | T=TK-273.15; % se c 10 | [names A B C] = AntoineGet(id); 11 | Ps = 10.^(A - B./(T+C)); % DINEI mmHg kai c 12 | Ps=0.0013332239*Ps ; % metatropi se bar 13 | %% ipologismos piramatikwn gamma 14 | gamma_exp=[]; 15 | X3 = 1-X1-X2; Y3=1-Y1-Y2; % calculate x3 16 | X = [X1 X2 X3]; Y=[Y1 Y2 Y3]; % create column array of x1 & x2 & X3 17 | for i=1:length( X1 ) 18 | for k=1:3 19 | gamma_exp(i,k)=Y(i,k).*Pbar(i)./(X(i,k).*Ps(i,k)); 20 | end 21 | end 22 | gamma_exp; 23 | %% isagogi statherwn uniquac gia to dedomeno migma 24 | R=1.98721; 25 | r=[2.5735 2.8675 1.4311]; 26 | q=[2.3360 2.4120 1.4320]; q1=q; 27 | gamma_cal=[]; 28 | %---------------------- 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /insert_data_exp_TERNset1.m: -------------------------------------------------------------------------------- 1 | clc;clear 2 | format long 3 | global TK R gamma_exp X r q q1 gamma_cal Y 4 | %% eisagogi dedomenwn 5 | components=3; 6 | [TK,Pbar,Y1,X1,Y2,X2] = importfile1('TERNARY_revised.DAT',3, 41); 7 | id = [37 63 44]; % antoiine id 8 | %TK=TK(1); % metrisis stin idia T 9 | T=TK-273.15; % se c 10 | [names A B C] = AntoineGet(id); 11 | Ps = 10.^(A - B./(T+C)); % DINEI mmHg kai c 12 | Ps=0.0013332239*Ps ; % metatropi se bar 13 | %% ipologismos piramatikwn gamma 14 | gamma_exp=[]; 15 | X3 = 1-X1-X2; Y3=1-Y1-Y2; % calculate x3 16 | X = [X1 X2 X3]; Y=[Y1 Y2 Y3]; % create column array of x1 & x2 & X3 17 | for i=1:length( X1 ) 18 | for k=1:3 19 | gamma_exp(i,k)=Y(i,k).*Pbar(i)./(X(i,k).*Ps(k)); 20 | end 21 | end 22 | gamma_exp; 23 | %% isagogi statherwn uniquac gia to dedomeno migma 24 | R=1.9872; 25 | r=[2.5735 1.4311 0.92]; 26 | q=[2.3360 1.432 1.4] ;q1=q; 27 | gamma_cal=[]; 28 | %---------------------- 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /insert_data_exp_TERNset1_TP.m: -------------------------------------------------------------------------------- 1 | clc;clear 2 | format long 3 | global TK R gamma_exp X r q q1 gamma_cal Y 4 | %% eisagogi dedomenwn 5 | components=3; 6 | [TK,Pbar,Y1,X1,Y2,X2] = importfile1('TERNARY_revised.DAT',3, 41); 7 | id = [37 63 44]; % antoiine id ---> load('AntoineTable.mat') 8 | %TK=TK(1); % metrisis stin idia T 9 | T=TK-273.15; % se c 10 | [names A B C] = AntoineGet(id); 11 | Ps = 10.^(A - B./(T+C)); % DINEI mmHg kai c 12 | Ps=0.0013332239*Ps ; % metatropi se bar 13 | %% ipologismos piramatikwn gamma 14 | gamma_exp=[]; 15 | X3 = 1-X1-X2; Y3=1-Y1-Y2; % calculate x3 16 | X = [X1 X2 X3]; Y=[Y1 Y2 Y3]; % create column array of x1 & x2 & X3 17 | for i=1:length( X1 ) 18 | for k=1:3 19 | gamma_exp(i,k)=Y(i,k).*Pbar(i)./(X(i,k).*Ps(i,k)); 20 | end 21 | end 22 | gamma_exp; 23 | %% isagogi statherwn uniquac gia to dedomeno migma 24 | R=1.9872; 25 | r=[2.5735 1.4311 0.92]; 26 | q=[2.3360 1.432 1.4] ;q1=q; 27 | gamma_cal=[]; 28 | %---------------------- 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /insert_data_exp_TERNset2_150.m: -------------------------------------------------------------------------------- 1 | clc;clear 2 | format long 3 | global TK R gamma_exp X r q q1 gamma_cal Y 4 | %% eisagogi dedomenwn 5 | components=3; 6 | [TK,Pbar,X1,X2,Y1,Y2] = importfileTERN_excel('Acet-CHCl3-meth150.xlsx','Acet-CHCl3-meth2',6,155); 7 | id = [37 49 2]; % antoiine id 8 | TK=TK(1); % metrisis stin idia T 9 | T=TK(1)-273.15; % se c 10 | [names A B C] = AntoineGet(id); 11 | Ps = 10.^(A - B./(T+C)); % DINEI mmHg kai c 12 | Ps=0.0013332239*Ps ; % metatropi se bar 13 | %% ipologismos piramatikwn gamma 14 | gamma_exp=[]; 15 | X3 = 1-X1-X2; Y3=1-Y1-Y2; % calculate x3 16 | X = [X1 X2 X3]; Y=[Y1 Y2 Y3]; % create column array of x1 & x2 & X3 17 | for i=1:length( X1 ) 18 | for k=1:3 19 | gamma_exp(i,k)=Y(i,k).*Pbar(i)./(X(i,k).*Ps(k)); 20 | end 21 | end 22 | gamma_exp; 23 | %% isagogi statherwn uniquac gia to dedomeno migma 24 | R=1.98721; 25 | r=[2.5735 2.8675 1.4311]; 26 | q=[2.3360 2.4120 1.4320]; q1=q; 27 | gamma_cal=[]; 28 | %---------------------- 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /insert_data_exp_TERNset2_36.m: -------------------------------------------------------------------------------- 1 | clc;clear 2 | format long 3 | global TK R gamma_exp X r q q1 gamma_cal Y 4 | %% eisagogi dedomenwn 5 | [TK,PmmHg,X1,X2,Y1,Y2] = importfileTERN_excel('Acet-CHCl3-meth36.xlsx','Acet-CHCl3-meth2',6,155); 6 | id = [37 49 2]; % antoiine id 7 | TK=TK(1); % metrisis stin idia T 8 | T=TK(1)-273.15; % se c 9 | [names A B C] = AntoineGet(id); 10 | Ps = 10.^(A - B./(T+C)); % DINEI mmHg kai c 11 | % Ps=0.0013332239*Ps ; % metatropi se bar 12 | %% ipologismos piramatikwn gamma 13 | gamma_exp=[]; 14 | X3 = 1-X1-X2; Y3=1-Y1-Y2; % calculate x3 15 | X = [X1 X2 X3]; Y=[Y1 Y2 Y3]; % create column array of x1 & x2 & X3 16 | for i=1:length( X1 ) 17 | for k=1:3 18 | gamma_exp(i,k)=Y(i,k).*PmmHg(i)./(X(i,k).*Ps(k)); 19 | end 20 | end 21 | gamma_exp; 22 | %% isagogi statherwn uniquac gia to dedomeno migma 23 | R=1.9872; 24 | r=[2.5735 2.87 1.4311]; 25 | q=[2.3360 2.41 1.4320]; q1=q; 26 | gamma_cal=[]; 27 | %---------------------- 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /insert_data_meth_ater.m: -------------------------------------------------------------------------------- 1 | clc;clear 2 | % format long 3 | global TK R gamma_exp X r q q1 gamma_cal 4 | %% eisagogi dedomenwn 5 | components=2; 6 | [TK,Pbar,Y1,X1] = importfile('1OL-H2O.DAT',3, 18); % orizoume kai apo pou mexri pou na diavasi 7 | id = [2 44]; % antoiine id 8 | TK=TK(1); % metrisis stin idia T 9 | T=TK(1)-273.15; % se c 10 | [names A B C] = AntoineGet(id); 11 | Ps = 10.^(A - B./(T+C)); % DINEI mmHg kai c 12 | Ps=0.0013332239*Ps ; % metatropi se bar 13 | %% ipologismos piramatikwn gamma 14 | gamma_exp=[]; 15 | X2 = 1-X1; % calculate x2 16 | X = [X1 X2]; % create a 2 column array of x1 & x2 17 | for i=1:length( X1 ) 18 | gamma_exp(i,1)=Y1(i).*Pbar(i)./(X1(i).*Ps(1)); 19 | gamma_exp(i,2)=(1-Y1(i)).*Pbar(i)./(X2(i).*Ps(2)); 20 | end 21 | gamma_exp; 22 | %% isagogi statherwn uniquac gia to dedomeno migma 23 | R=1.9872; 24 | r=[1.4311 0.92]; 25 | q=[1.432 1.4] ;q1=q; 26 | gamma_cal=[]; 27 | %---------------------- 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /insert_data_meth_water_TP.m: -------------------------------------------------------------------------------- 1 | clc;clear 2 | % format long 3 | global TK R gamma_exp X r q q1 gamma_cal 4 | %% eisagogi dedomenwn 5 | components=2; 6 | [TK,Pbar,Y1,X1] = importfile('1OL-H2O.DAT',3, 18); % orizoume kai apo pou mexri pou na diavasi 7 | id = [2 44]; % antoiine id ---> load('AntoineTable.mat') 8 | % TK=TK(1); % metrisis stin idia T 9 | T=TK-273.15; % se c 10 | [names A B C] = AntoineGet(id); 11 | Ps = 10.^(A - B./(T+C)); % DINEI mmHg kai c 12 | Ps=0.0013332239*Ps ; % metatropi se bar 13 | %% ipologismos piramatikwn gamma 14 | gamma_exp=[]; 15 | X2 = 1-X1; % calculate x2 16 | X = [X1 X2]; % create a 2 column array of x1 & x2 17 | for i=1:length( X1 ) 18 | gamma_exp(i,1)=Y1(i).*Pbar(i)./(X1(i).*Ps(i,1)); 19 | gamma_exp(i,2)=(1-Y1(i)).*Pbar(i)./(X2(i).*Ps(i,2)); 20 | end 21 | gamma_exp; 22 | %% isagogi statherwn uniquac gia to dedomeno migma 23 | R=1.9872; 24 | r=[1.4311 0.92]; 25 | q=[1.432 1.4] ;q1=q; 26 | gamma_cal=[]; 27 | %---------------------- 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /insert_inglesiasTP.m: -------------------------------------------------------------------------------- 1 | clc;clear 2 | format long 3 | global TK R gamma_exp X r q q1 gamma_cal Y 4 | %% eisagogi dedomenwn 5 | components=3; 6 | [TK,Pbar,X1,X2,Y1,Y2] = importfileTERN_excel('inglesias.xlsx','Sheet1',1,122); 7 | id = [37 2 44]; % antoiine id 8 | % TK=TK(1); % metrisis stin idia T 9 | T=TK-273.15; % se c 10 | [names A B C] = AntoineGet(id); 11 | Ps = 10.^(A - B./(T+C)); % DINEI mmHg kai c 12 | Ps=0.0013332239*Ps ; % metatropi se bar 13 | %% ipologismos piramatikwn gamma 14 | gamma_exp=[]; 15 | X3 = 1-X1-X2; Y3=1-Y1-Y2; % calculate x3 16 | X = [X1 X2 X3]; Y=[Y1 Y2 Y3]; % create column array of x1 & x2 & X3 17 | for i=1:length( X1 ) 18 | for k=1:3 19 | gamma_exp(i,k)=Y(i,k).*Pbar(i)./(X(i,k).*Ps(i,k)); 20 | end 21 | end 22 | gamma_exp; 23 | %% isagogi statherwn uniquac gia to dedomeno migma 24 | R=1.98721; 25 | r=[2.5735 2.8675 1.4311]; 26 | q=[2.3360 2.4120 1.4320]; q1=q; 27 | gamma_cal=[]; 28 | %---------------------- 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /insert_quaternary1.m: -------------------------------------------------------------------------------- 1 | clc;clear 2 | format long 3 | global TK R gamma_exp X r q q1 gamma_cal Y 4 | %% eisagogi dedomenwn 5 | components=4; 6 | [TK,Pmmhg,X1,X2,X3,Y1,Y2,Y3,gamma_exp1,gamma_exp2,gamma_exp3,gamma_exp4] = importfile2('quaternary1_GAMMA.xlsx','SHEET1',4,37);%IMPORT_QUERN_WITH_GAMMA 7 | id = [39 3 44 47];% antoiine id ---> load('AntoineTable.mat') 8 | % TK=TK(1); % metrisis stin idia T 9 | T=TK-273.15; % se c 10 | [names A B C] = AntoineGet(id); 11 | Ps = 10.^(A - B./(T+C)); % DINEI mmHg kai c 12 | % Ps=0.0013332239*Ps ; % metatropi se bar 13 | %% ipologismos piramatikwn gamma 14 | gamma_exp=[]; 15 | X4 = 1-X1-X2-X3; Y4=1-Y1-Y2-Y3; % calculate x3 16 | X = [X1 X2 X3 X4]; Y=[Y1 Y2 Y3 Y4]; % create column array of x1 & x2 & X3 17 | % for i=1:length( X1 ) 18 | % for k=1:components 19 | gamma_exp=[gamma_exp1 gamma_exp2 gamma_exp3 gamma_exp4]; 20 | % gamma_exp(i,k)=Y(i,k).*Pbar(i)./(X(i,k).*Ps(i,k)); 21 | % end 22 | % end 23 | gamma_exp; 24 | %% isagogi statherwn uniquac gia to dedomeno migma 25 | R=1.98721; 26 | r=[3.48 2.10550 0.92000 1.90]; 27 | q=[3.12 1.97200 1.40000 1.80]; q1=q; 28 | gamma_cal=[]; 29 | %---------------------- 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /lastexplore.m: -------------------------------------------------------------------------------- 1 | function [ Du_new] = lastexplore(MAX,MIN,Du_old) 2 | 3 | numb1=rand; 4 | 5 | ra=0.90+rand*(0.1); 6 | ra2=(995+rand*(5))/1000; 7 | if numb1>0.5 8 | %afksanete 9 | Du_new=Du_old+(MAX-Du_old)*(1-ra^(1-ra2)); 10 | else 11 | %mionete 12 | Du_new=Du_old-(Du_old-MIN)*(1-ra^(1-ra2)); 13 | end 14 | -------------------------------------------------------------------------------- /levmar.m: -------------------------------------------------------------------------------- 1 | function [x,histout,costdata] = levmar(x0,f,tol,maxit) 2 | % 3 | % C. T. Kelley, Dec 14, 1997 4 | % 5 | % This code comes with no guarantee or warranty of any kind. 6 | % 7 | % function [x,histout,costdata] = levmar(x0,f,tol,maxit) 8 | % 9 | % Levenberg-Marquardt code, trust region control of LM parameter 10 | % 11 | % 12 | % Input: x0 = initial iterate 13 | % f = r^T r/2 = objective function, 14 | % the calling sequence for f should be 15 | % [fout,gout,jac]=f(x) where fout=f(x) is a scalar 16 | % gout = jac^T r = grad f(x) is a COLUMN vector 17 | % and jac = r' = Jacobian of r is an M x N matrix 18 | % tol = termination criterion norm(grad) < tol 19 | % maxit = maximum iterations (optional) default = 100 20 | % 21 | % Output: x = solution 22 | % histout = iteration history 23 | % Each row of histout is 24 | % [norm(grad), f, number of stepsize cuts, iteration count] 25 | % costdata = [num f, num grad, num hess] (for levmar, num hess=0) 26 | % 27 | % At this stage all iteration parameters are hardwired in the code. 28 | % 29 | % 30 | debug=1; 31 | if nargin < 4 32 | maxit=100; 33 | end 34 | itc=1; xc=x0; 35 | [fc,gc,jac,rout]=feval(f,xc); 36 | nu0=.001d0; 37 | nu0=1.d0; 38 | mvar=length(gc); nvar=length(xc); 39 | nfun=1; ngrad=1; numh=0; 40 | numf=1; numg=1; numh=0; 41 | ithist(1,1)=norm(gc); ithist(1,2) = fc; ithist(1,4)=itc-1; ithist(1,3)=0; 42 | nu=norm(gc); 43 | while(norm(gc) > tol & itc <= maxit) 44 | itc=itc+1; 45 | % hc=(jac'*jac)+ nu*eye(nvar); 46 | % dc=hc\gc; 47 | hc=[jac; sqrt(nu)*eye(nvar)]; 48 | gcx=[rout; zeros(nvar,1)]; 49 | dc=-hc\gcx; 50 | xt=xc+dc; 51 | [xp,nup,idid]=trtestlm(f,xc,xt,fc,jac,gc,nu,nu0,rout); 52 | if idid > 30 53 | error('too many iterations in TR solve') 54 | end 55 | xc=xp; nu=nup; numf=numf+idid; 56 | % 57 | % Bug fixed on July 23, 2016 <------- YEESH! 58 | % This was a pretty bad bug and really slowed things down. 59 | % Thanks to Paul Hursky for finding this. 60 | % 61 | % if idid > 1 62 | [fc,gc,jac,rout]=feval(f,xc); numf = numf+1; numg=numg+1; 63 | % end 64 | ithist(itc,1)=norm(gc); ithist(itc,2) = fc; 65 | ithist(itc,4)=itc-1; ithist(itc,3)=idid; 66 | if debug == 1 67 | ithist(itc,:) 68 | end 69 | end 70 | x=xc; histout=ithist(1:itc,:); 71 | costdata=[numf, numg, numh]; 72 | % 73 | % 74 | % 75 | function [xp,nup,idid]=trtestlm(f,xc,xt,fc,jac,gc,nu,nu0,rout); 76 | mu0=0.d0; mulow=.25; muhigh=.75; mup=2.d0; mdown=.5d0; 77 | z=xc; nvar=length(z); numft=0; numgt=0; itr=0; 78 | while z==xc & itr <= 30 79 | ft=feval(f,xt); 80 | itr=itr+1; 81 | s=xt-xc; ared=fc-ft; pred=-(gc'*s)*.5; 82 | rat = ared/pred; 83 | if rat < mu0 84 | nu=max(nu*mup,nu0); 85 | % hc=(jac'*jac)+ nu*eye(nvar); 86 | % dc=hc\gc; 87 | hc=[jac; sqrt(nu)*eye(nvar)]; 88 | gcx=[rout; zeros(nvar,1)]; 89 | dc=-hc\gcx; 90 | xt=xc+dc; 91 | elseif rat < mulow 92 | z=xt; nu=max(nu*mup,nu0); 93 | else 94 | z=xt; 95 | if rat > muhigh 96 | nu=mdown*nu; 97 | if nu < nu0 nu=0.d0; end 98 | end 99 | end 100 | end 101 | nup=nu; xp=z; idid=itr; -------------------------------------------------------------------------------- /lsqnonlinmine.m: -------------------------------------------------------------------------------- 1 | function [xCurrent,Resnorm,FVAL,EXITFLAG,OUTPUT,LAMBDA,JACOB] = lsqnonlin(FUN,xCurrent,LB,UB,options,varargin) 2 | %LSQNONLIN solves non-linear least squares problems. 3 | % LSQNONLIN attempts to solve problems of the form: 4 | % min sum {FUN(X).^2} where X and the values returned by FUN can be 5 | % X vectors or matrices. 6 | % 7 | % LSQNONLIN implements two different algorithms: trust region reflective 8 | % and Levenberg-Marquardt. Choose one via the option Algorithm: for 9 | % instance, to choose Levenberg-Marquardt, set 10 | % OPTIONS = optimoptions('lsqnonlin', 'Algorithm','levenberg-marquardt'), 11 | % and then pass OPTIONS to LSQNONLIN. 12 | % 13 | % X = LSQNONLIN(FUN,X0) starts at the matrix X0 and finds a minimum X to 14 | % the sum of squares of the functions in FUN. FUN accepts input X 15 | % and returns a vector (or matrix) of function values F evaluated 16 | % at X. NOTE: FUN should return FUN(X) and not the sum-of-squares 17 | % sum(FUN(X).^2)). (FUN(X) is summed and squared implicitly in the 18 | % algorithm.) 19 | % 20 | % X = LSQNONLIN(FUN,X0,LB,UB) defines a set of lower and upper bounds on 21 | % the design variables, X, so that the solution is in the range LB <= X 22 | % <= UB. Use empty matrices for LB and UB if no bounds exist. Set LB(i) 23 | % = -Inf if X(i) is unbounded below; set UB(i) = Inf if X(i) is 24 | % unbounded above. 25 | % 26 | % X = LSQNONLIN(FUN,X0,LB,UB,OPTIONS) minimizes with the default 27 | % optimization parameters replaced by values in OPTIONS, an argument 28 | % created with the OPTIMOPTIONS function. See OPTIMOPTIONS for details. 29 | % Use the Jacobian option to specify that FUN also returns a second 30 | % output argument J that is the Jacobian matrix at the point X. If FUN 31 | % returns a vector F of m components when X has length n, then J is an 32 | % m-by-n matrix where J(i,j) is the partial derivative of F(i) with 33 | % respect to x(j). (Note that the Jacobian J is the transpose of the 34 | % gradient of F.) 35 | % 36 | % X = LSQNONLIN(PROBLEM) solves the non-linear least squares problem 37 | % defined in PROBLEM. PROBLEM is a structure with the function FUN in 38 | % PROBLEM.objective, the start point in PROBLEM.x0, the lower bounds in 39 | % PROBLEM.lb, the upper bounds in PROBLEM.ub, the options structure in 40 | % PROBLEM.options, and solver name 'lsqnonlin' in PROBLEM.solver. Use 41 | % this syntax to solve at the command line a problem exported from 42 | % OPTIMTOOL. The structure PROBLEM must have all the fields. 43 | % 44 | % [X,RESNORM] = LSQNONLIN(FUN,X0,...) returns 45 | % the value of the squared 2-norm of the residual at X: sum(FUN(X).^2). 46 | % 47 | % [X,RESNORM,RESIDUAL] = LSQNONLIN(FUN,X0,...) returns the value of the 48 | % residual at the solution X: RESIDUAL = FUN(X). 49 | % 50 | % [X,RESNORM,RESIDUAL,EXITFLAG] = LSQNONLIN(FUN,X0,...) returns an 51 | % EXITFLAG that describes the exit condition of LSQNONLIN. Possible 52 | % values of EXITFLAG and the corresponding exit conditions are listed 53 | % below. See the documentation for a complete description. 54 | % 55 | % 1 LSQNONLIN converged to a solution. 56 | % 2 Change in X too small. 57 | % 3 Change in RESNORM too small. 58 | % 4 Computed search direction too small. 59 | % 0 Too many function evaluations or iterations. 60 | % -1 Stopped by output/plot function. 61 | % -2 Bounds are inconsistent. 62 | % 63 | % [X,RESNORM,RESIDUAL,EXITFLAG,OUTPUT] = LSQNONLIN(FUN,X0,...) returns a 64 | % structure OUTPUT with the number of iterations taken in 65 | % OUTPUT.iterations, the number of function evaluations in 66 | % OUTPUT.funcCount, the algorithm used in OUTPUT.algorithm, the number 67 | % of CG iterations (if used) in OUTPUT.cgiterations, the first-order 68 | % optimality (if used) in OUTPUT.firstorderopt, and the exit message in 69 | % OUTPUT.message. 70 | % 71 | % [X,RESNORM,RESIDUAL,EXITFLAG,OUTPUT,LAMBDA] = LSQNONLIN(FUN,X0,...) 72 | % returns the set of Lagrangian multipliers, LAMBDA, at the solution: 73 | % LAMBDA.lower for LB and LAMBDA.upper for UB. 74 | % 75 | % [X,RESNORM,RESIDUAL,EXITFLAG,OUTPUT,LAMBDA,JACOBIAN] = LSQNONLIN(FUN, 76 | % X0,...) returns the Jacobian of FUN at X. 77 | % 78 | % Examples 79 | % FUN can be specified using @: 80 | % x = lsqnonlin(@myfun,[2 3 4]) 81 | % 82 | % where myfun is a MATLAB function such as: 83 | % 84 | % function F = myfun(x) 85 | % F = sin(x); 86 | % 87 | % FUN can also be an anonymous function: 88 | % 89 | % x = lsqnonlin(@(x) sin(3*x),[1 4]) 90 | % 91 | % If FUN is parameterized, you can use anonymous functions to capture the 92 | % problem-dependent parameters. Suppose you want to solve the non-linear 93 | % least squares problem given in the function myfun, which is 94 | % parameterized by its second argument c. Here myfun is a MATLAB file 95 | % function such as 96 | % 97 | % function F = myfun(x,c) 98 | % F = [ 2*x(1) - exp(c*x(1)) 99 | % -x(1) - exp(c*x(2)) 100 | % x(1) - x(2) ]; 101 | % 102 | % To solve the least squares problem for a specific value of c, first 103 | % assign the value to c. Then create a one-argument anonymous function 104 | % that captures that value of c and calls myfun with two arguments. 105 | % Finally, pass this anonymous function to LSQNONLIN: 106 | % 107 | % c = -1; % define parameter first 108 | % x = lsqnonlin(@(x) myfun(x,c),[1;1]) 109 | % 110 | % See also OPTIMOPTIONS, LSQCURVEFIT, FSOLVE, @, INLINE. 111 | 112 | % Copyright 1990-2012 The MathWorks, Inc. 113 | 114 | % ------------Initialization---------------- 115 | defaultopt = struct(... 116 | 'Algorithm','trust-region-reflective',... 117 | 'DerivativeCheck','off',... 118 | 'Diagnostics','off',... 119 | 'DiffMaxChange',Inf,... 120 | 'DiffMinChange',0,... 121 | 'Display','final',... 122 | 'FinDiffRelStep', [], ... 123 | 'FinDiffType','forward',... 124 | 'FunValCheck','off',... 125 | 'Jacobian','off',... 126 | 'JacobMult',[],... 127 | 'JacobPattern','sparse(ones(Jrows,Jcols))',... 128 | 'MaxFunEvals',500,...%% 129 | 'MaxIter',10^10,...%% 130 | 'MaxPCGIter','max(1,floor(numberOfVariables/2))',... 131 | 'OutputFcn',[],... 132 | 'PlotFcns',[],... 133 | 'PrecondBandWidth',Inf,... 134 | 'ScaleProblem','none',... 135 | 'TolFun',0,... 136 | 'TolPCG',0.1,... 137 | 'TolX',1e-3,...%% 138 | 'TypicalX','ones(numberOfVariables,1)'); 139 | 140 | % If just 'defaults' passed in, return the default options in X 141 | if nargin==1 && nargout <= 1 && isequal(FUN,'defaults') 142 | xCurrent = defaultopt; 143 | return 144 | end 145 | 146 | if nargin < 5 147 | options = []; 148 | if nargin < 4 149 | UB = []; 150 | if nargin < 3 151 | LB = []; 152 | end 153 | end 154 | end 155 | 156 | problemInput = false; 157 | if nargin == 1 158 | if isa(FUN,'struct') 159 | problemInput = true; 160 | [FUN,xCurrent,LB,UB,options] = separateOptimStruct(FUN); 161 | else % Single input and non-structure. 162 | error(message('optim:lsqnonlin:InputArg')); 163 | end 164 | end 165 | 166 | % Prepare the options for the solver 167 | [options, optionFeedback] = prepareOptionsForSolver(options, 'lsqnonlin'); 168 | 169 | if nargin < 2 && ~problemInput 170 | error(message('optim:lsqnonlin:NotEnoughInputs')) 171 | end 172 | 173 | % Check for non-double inputs 174 | msg = isoptimargdbl('LSQNONLIN', {'X0','LB','UB'}, ... 175 | xCurrent,LB, UB); 176 | if ~isempty(msg) 177 | error('optim:lsqnonlin:NonDoubleInput',msg); 178 | end 179 | 180 | caller = 'lsqnonlin'; 181 | [funfcn,mtxmpy,flags,sizes,funValCheck,xstart,lb,ub,EXITFLAG,Resnorm,FVAL,LAMBDA, ... 182 | JACOB,OUTPUT,earlyTermination] = lsqnsetup(FUN,xCurrent,LB,UB,options,defaultopt, ... 183 | caller,nargout,length(varargin)); 184 | if earlyTermination 185 | return % premature return because of problem detected in lsqnsetup() 186 | end 187 | 188 | xCurrent(:) = xstart; % reshape back to user shape before evaluation 189 | % Catch any error in user objective during initial evaluation only 190 | switch funfcn{1} 191 | case 'fun' 192 | try 193 | initVals.F = feval(funfcn{3},xCurrent,varargin{:}); 194 | catch userFcn_ME 195 | optim_ME = MException('optim:lsqnonlin:InvalidFUN', ... 196 | getString(message('optim:lsqnonlin:InvalidFUN'))); 197 | userFcn_ME = addCause(userFcn_ME,optim_ME); 198 | rethrow(userFcn_ME) 199 | end 200 | initVals.J = []; 201 | case 'fungrad' 202 | try 203 | [initVals.F,initVals.J] = feval(funfcn{3},xCurrent,varargin{:}); 204 | catch userFcn_ME 205 | optim_ME = MException('optim:lsqnonlin:InvalidFUN', ... 206 | getString(message('optim:lsqnonlin:InvalidFUN'))); 207 | userFcn_ME = addCause(userFcn_ME,optim_ME); 208 | rethrow(userFcn_ME) 209 | end 210 | case 'fun_then_grad' 211 | try 212 | initVals.F = feval(funfcn{3},xCurrent,varargin{:}); 213 | catch userFcn_ME 214 | optim_ME = MException('optim:lsqnonlin:InvalidFUN', ... 215 | getString(message('optim:lsqnonlin:InvalidFUN'))); 216 | userFcn_ME = addCause(userFcn_ME,optim_ME); 217 | rethrow(userFcn_ME) 218 | end 219 | try 220 | initVals.J = feval(funfcn{4},xCurrent,varargin{:}); 221 | catch userFcn_ME 222 | optim_ME = MException('optim:lsqnonlin:InvalidFUN', ... 223 | getString(message('optim:lsqnonlin:InvalidJacobFun'))); 224 | userFcn_ME = addCause(userFcn_ME,optim_ME); 225 | rethrow(userFcn_ME) 226 | end 227 | otherwise 228 | error(message('optim:lsqnonlin:UndefCallType')) 229 | end 230 | 231 | % Check for non-double data typed values returned by user functions 232 | if ~isempty( isoptimargdbl('LSQNONLIN', {'F','J'}, initVals.F, initVals.J) ) 233 | error('optim:lsqnonlin:NonDoubleFunVal',getString(message('optimlib:commonMsgs:NonDoubleFunVal','LSQNONLIN'))); 234 | end 235 | 236 | [xCurrent,Resnorm,FVAL,EXITFLAG,OUTPUT,LAMBDA,JACOB] = ... 237 | lsqncommon(funfcn,xCurrent,lb,ub,options,defaultopt,caller,... 238 | initVals,sizes,flags,mtxmpy,optionFeedback,varargin{:}); 239 | -------------------------------------------------------------------------------- /matlabbig.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pngts/Nonlinear-parameter-estimation-in-thermodynamic-models/93bd1a062f616e61b0d7214b293b14d48dd16c81/matlabbig.mat -------------------------------------------------------------------------------- /myfminimax.m: -------------------------------------------------------------------------------- 1 | function [x,fval,maxfval,exitflag,output,lambda] = myfminimax(x0,MaxFunctionEvaluations_Data,OptimalityTolerance_Data,ConstraintTolerance_Data) 2 | %% This is an auto generated MATLAB file from Optimization Tool. 3 | 4 | %% Start with the default options 5 | options = optimoptions('fminimax'); 6 | %% Modify options setting 7 | options = optimoptions(options,'Display', 'off'); 8 | options = optimoptions(options,'MaxFunctionEvaluations', MaxFunctionEvaluations_Data); 9 | options = optimoptions(options,'OptimalityTolerance', OptimalityTolerance_Data); 10 | options = optimoptions(options,'FunctionTolerance', OptimalityTolerance_Data); 11 | options = optimoptions(options,'ConstraintTolerance', ConstraintTolerance_Data); 12 | [x,fval,maxfval,exitflag,output,lambda] = ... 13 | fminimax(@ff,x0,[],[],[],[],[],[],[],options); 14 | -------------------------------------------------------------------------------- /myfminsearch.m: -------------------------------------------------------------------------------- 1 | function [x,fval,exitflag,output] = myfminsearch(ff,x0,MaxFunEvals_Data,MaxIter_Data) 2 | %% This is an auto generated MATLAB file from Optimization Tool. 3 | 4 | %% Start with the default options 5 | options = optimset; 6 | %% Modify options setting 7 | options = optimset(options,'Display', 'off'); 8 | options = optimset(options,'MaxFunEvals', MaxFunEvals_Data); 9 | options = optimset(options,'MaxIter', MaxIter_Data); 10 | [x,fval,exitflag,output] = ... 11 | fminsearch(ff,x0,options); 12 | -------------------------------------------------------------------------------- /option_clas_solver.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pngts/Nonlinear-parameter-estimation-in-thermodynamic-models/93bd1a062f616e61b0d7214b293b14d48dd16c81/option_clas_solver.mat -------------------------------------------------------------------------------- /optionfminimax.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pngts/Nonlinear-parameter-estimation-in-thermodynamic-models/93bd1a062f616e61b0d7214b293b14d48dd16c81/optionfminimax.mat -------------------------------------------------------------------------------- /petama.m: -------------------------------------------------------------------------------- 1 | function [fitness]=petama(du12,du13,du21,du23,du31,du32) 2 | global TK R gamma_exp X r q q1 gamma_cal 3 | %% prota ipologizonte to gammaCalc apo tin uniquac 4 | %du12=-130.2535*1.9872;du13=-81.56071*1.9872;du21=-34.51268*1.9872;du23=-873.6794*1.9872;du31=179.9613*1.9872;du32=304.4958*1.9872; 5 | %du12=-315.49*R;du13=378.93*R;du21=-228.24*R;du23=-52.15*R;du31=691.51*R;du32=-142.79*R; 6 | % du12=892.176910603683;du13=493.755343490955;du21=-426.625512950253;du23=-425.872500366702;du31=34.5200694478557;du32=615.206598583084; 7 | 8 | tau=[1 exp(-du12./TK./R) exp(-du13./TK./R);exp(-du21./TK./R) 1 exp(-du23./TK./R);exp(-du31./TK./R) exp(-du32./TK./R) 1] ; 9 | error=0;error1=0; 10 | for i=1:length(X) 11 | x=[X(i,1) X(i,2) X(i,3)]; 12 | gamma_cal(i,:)=uniquac(x, r, q, q1,tau); 13 | error=error1 +((gamma_cal(i,1)-gamma_exp(i,1))/gamma_exp(i,1))^2 +((gamma_cal(i,2)-gamma_exp(i,2))/gamma_exp(i,2))^2 +((gamma_cal(i,3)-gamma_exp(i,3))/gamma_exp(i,3))^2; 14 | %error=error1 +abs(gamma_cal(i,1)-gamma_exp(i,1))+abs(gamma_cal(i,2)-gamma_exp(i,2))+abs(gamma_cal(i,3)-gamma_exp(i,3)) ; 15 | error1=error; 16 | end 17 | fitness=1/error; -------------------------------------------------------------------------------- /props.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pngts/Nonlinear-parameter-estimation-in-thermodynamic-models/93bd1a062f616e61b0d7214b293b14d48dd16c81/props.mat -------------------------------------------------------------------------------- /propsTableBrowse.m: -------------------------------------------------------------------------------- 1 | %This script is to browse the Antoine table to see the 2 | %index values and temperature limits. 3 | if(~exist('props','var')) 4 | db = load ('props.mat'); 5 | props = db.props; clear db; 6 | end 7 | for i=1:length(props(:,1)) 8 | fprintf('%d %s %s\n', i,props{i,2},props{i,3}); 9 | end 10 | 11 | % ver 1.02 6/5/12 use structured variable with 'load', improved printing 12 | % version 1.01 4/9/12 modified for new props.mat with new short name column -------------------------------------------------------------------------------- /quaternary.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pngts/Nonlinear-parameter-estimation-in-thermodynamic-models/93bd1a062f616e61b0d7214b293b14d48dd16c81/quaternary.pdf -------------------------------------------------------------------------------- /quaternary1.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pngts/Nonlinear-parameter-estimation-in-thermodynamic-models/93bd1a062f616e61b0d7214b293b14d48dd16c81/quaternary1.xlsx -------------------------------------------------------------------------------- /quaternary1_GAMMA.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pngts/Nonlinear-parameter-estimation-in-thermodynamic-models/93bd1a062f616e61b0d7214b293b14d48dd16c81/quaternary1_GAMMA.xlsx -------------------------------------------------------------------------------- /readme.txt: -------------------------------------------------------------------------------- 1 | Antoine coefficients for: log10(Psat[mmHg])=A-B/(T[oC]+C) 2 | -------------------------------------------------------------------------------- /rosen.m: -------------------------------------------------------------------------------- 1 | function r = rosen(x) 2 | %%%%%%%%%%%%%%%%%%%%% Rosenbrock valey with a constraint 3 | 4 | R = sqrt(x(1)^2+x(2)^2)-.5; 5 | %R = sqrt(x(1)^2+x(2)^2)-1; 6 | %R = sqrt(x(1)^2+x(2)^2)-2; 7 | 8 | % Residuals: 9 | r = [ 10*(x(2)-x(1)^2) % first part 10 | 1-x(1) % second part 11 | (R>0)*R*500. % penalty 12 | ]; 13 | -------------------------------------------------------------------------------- /rouletteDU.m: -------------------------------------------------------------------------------- 1 | function [i] = rouletteDU(fit_values,fitness) 2 | n_rand = rand()*fitness; 3 | sum_fit = 0; 4 | for i=1:length(fit_values), 5 | sum_fit = sum_fit + fit_values(i); 6 | if sum_fit >= n_rand 7 | break; 8 | end 9 | end -------------------------------------------------------------------------------- /run_GA.m: -------------------------------------------------------------------------------- 1 | insert_data_gammaexp 2 | NO_exp=100;%arithmos piramaton 3 | All_generations_RESULTS=[]; 4 | k=1; 5 | ga_test1 6 | while k