function [y1] = ANN_Ruffini_et_al_2021(x1)
%Artificial Neural Network of Ruffini et al. 2021
%
% Created by Mr. Gioele Ruffini 
% 
% [y1] = Ruffini_et_al_2021_ANN(x1) function uses these arguments:
%   x1 = 6x1 array, with variables:  L_f/(h_0-h_f), H_0/h_0, a_0/h_0, L_0/h_0, T(g/h_0)^{1/2} and h_f/h_0,
% and returns:
%   y1 = 2x1 array, with varibles: K_b and K_{a,b}.
% For the complete notation of the variables refer to Ruffini et al.,(2021).

%

% ===== NEURAL NETWORK CONSTANTS =====

% Input
x1_step1.xoffset = [-83.333;0.067;0.035;2;3.542;0];
x1_step1.gain = [0.012000048000192;3.83141762452107;3.6101083032491;0.25;0.31210986267166;1.05263157894737];
x1_step1.ymin = -1;

% Hidden Layer 1
b1 = [2.7287054270780770615;1.7854081602200586598;-1.7648981308471536344;1.2000279131436144553;1.3712027575005429902;-1.4015779845380913482;-0.032711117231567124475;0.28265656108288889081;0.23740939638520847099;1.0560638100414045937;-1.7002218181707118294;0.37648355976476455265;1.1736178179750451633;-1.5095300383973855318;-2.3011336939240196742];
W1_1 = [-0.52963090153967140594 -0.6884481902391539343 1.0927641641870260436 0.90962587984867349089 -0.43099270368824760258 0.53696717590795317587;-0.66124659168397614817 0.34425992049444187337 0.51866608851641260447 -0.80130883100543781605 -0.55719416988601855323 2.1532655607197415115;0.11888408325547157596 -0.75610696742116911828 0.39900063408543950949 0.87842230176335023284 -0.51741563561139491956 -1.9777240720131203933;-1.3105995163761730016 -0.11005542716615650256 1.5048577282392405774 0.93926895228924123238 -0.38606020123607592831 -0.10536815263143917143;-1.8949832815943321584 -0.8188300951185784049 -0.50275187428758782993 0.65288837070269689633 0.21865692258043406548 -0.1241769761055781518;1.7557093986880956127 -0.61584419338441498404 -1.2368395922182928715 0.91045386649944426427 -0.91212065664124186704 0.36680020808624175244;0.36096958038382220835 1.3275194011316360232 1.1715761177195398446 0.61962085952216972018 0.87869096133666979576 1.3374146623139970824;0.10562397255791690365 -1.2521571808222964339 -0.028301703794986685092 -0.18325109974403058777 -1.218842656023726434 -1.1233413396160369935;-1.1365091714721331506 -0.4485402064133951483 1.241368613986871372 0.87859112583995502277 -0.21095894884757668275 -1.3280680465471412788;0.44840955164162127344 0.81779337828726839099 -0.30365541936771689446 1.1310905993440691919 1.2735664694825872267 -0.29111448417294044644;-0.4787023324202304142 0.95619314664611376742 -0.30343371970101135071 -1.0019011013980234637 0.30485700154937828144 -1.9277208597528989742;1.0139736136323207472 -0.072408965808479941462 1.1508109709085636574 0.72566001632168242175 0.7133540906894288991 -1.7134358351986556102;0.82202136448242191236 0.48331305239953697983 -1.5005467749275855915 1.1575012447311010533 0.67157927247664550574 0.086054803142237012992;-0.21390214850935168611 -0.9094081474553620259 -1.0225263737430523303 -0.51225002182571777176 0.84517796826026547752 -1.5318066446626581456;-0.45611095970242698794 -0.23998606262984303883 1.346153271661001849 -0.48491769456069050426 -0.27679725813762107167 1.3098746968158003767];

% Hidden Layer 2
b2 = [-1.5673438799569874291;-1.5309938029802265813;1.1175589934417307081;-1.0193906521977538215;-0.40784031311395385622;-0.33975043716521780013;0.20314777402906442072;0.011717292354980243796;0.11453298887079227386;-0.56365629540227357719;-0.92800686715918323522;-0.95956487391698930267;-0.92424427361327543551;1.5773659706286404791;-1.8243608430557558542];
W2_1 = [0.22681733566213141406 -0.13098898023435981419 -0.78610888041753179678 0.13161429198490859349 0.5489199230289671938 -0.63648887648993857091 0.34253947535661627422 -0.72580900968497330528 -0.38735285893385812406 0.70376228050723499408 0.19152053839075192099 0.42154613994315925929 0.77143083219837338405 0.33561209323712226649 -0.13766681345633513533;-0.18044717755420480731 0.11289524010278487176 0.72001119774057342759 -0.18012469518300028293 0.066565712525208486916 -0.71794551287029262365 -0.42328582313217116839 0.69532203499051525863 0.54852882143482051269 0.34392942663043146734 -0.29443833823723009058 0.065101284642551715542 0.30983097558725214427 0.72588071023249189917 -0.044998595208012533153;-0.62724939446663996456 0.066698680141235394681 -0.27039751335241807295 -0.29513486560003104886 0.15825429017554917821 -0.67302253998229777388 0.6409210626553254464 -0.39399968989275718778 0.32781868993415730351 0.74824770694724540565 0.61010097977107247136 -0.062679272436913319178 -0.46447230933705091482 -0.60249148496460758206 0.37313118977370418605;0.13025695240284643206 0.64726296267206029356 0.39030517856547458644 -0.31953780307327672716 0.83783957300000544421 0.20660464519200943956 0.84803530974759822048 0.75558048117081677564 1.0086465579210390775 -0.069963771986960646143 0.007732137352052664836 0.55259222989472522869 -0.37412075697993429912 0.29220004092897833292 0.58185337397333170006;0.63662620922070922713 -0.63849562449090313532 0.70424476618977704945 0.64805169209649615691 -0.098248355824385152912 -0.12541491006583305179 -0.75774853666895036763 0.49471528621620303179 -0.023291402982627669449 0.76036865291854605076 -0.35464124107820632625 0.086051471208617558162 0.14204987035562968711 -0.15187687403597494029 -0.18200281240075999456;0.16518983970958175944 -0.81315546918163150725 0.42812101960429249647 0.21280167111396941504 -0.38170813379838280932 -0.53693519185813587402 -0.41948835977190174207 -0.41544108682240410424 -1.5350943288158138689 0.58396064582398643505 1.0827732023696619024 0.62990789716771444784 0.73515953426719982122 0.49694268431747268266 0.1809866051137474785;-0.52855654535705554053 -0.48583118285226495336 0.48464810848302752877 -0.60930882720116830154 0.73710877976552047208 0.70796516721489588519 0.29227852980497792679 0.066556894799275900798 -0.2704672803360930744 -0.44827053653606052652 -0.42723430428985503804 -0.28092678229629508557 -0.50735876698485082859 0.44495692520964436056 -0.34280231135910116391;0.36890827009813426107 -0.8663642338090880024 0.82022726269277768107 0.50257746373820288976 -0.24941846484158150532 -1.5060953333513484864 0.14812236662462993642 0.45917702018136963282 -0.16105282417071806189 -0.46004398608669672122 1.4622397380185496729 0.72714959423015645967 0.16415083187865053826 0.35983565676664602817 -0.4071859737861046602;-0.1204923433506792374 0.74317129208076804225 -0.47213906435567914999 0.79911773667438446012 0.49521532020376513028 0.15132468536799514869 -0.07587107415804181243 0.29628318887790400238 0.031943236527793260338 -0.30610061300462476641 -0.34108795130682900698 -0.62213073678884378559 -0.5886612297397985083 -0.34116187099511724456 -0.45563617787864252318;-0.47733448464476019302 -0.060049578301967540539 -0.15128845789387193599 0.3727599746937140246 -0.51690405453223053911 -0.52656140160495412683 0.43790714022425214491 0.59452568634034685946 -0.45504226463481300957 -0.068994703151794289919 0.12135034230788614706 0.83099771771248120977 -0.032319756317530617951 -0.48344482802269428401 0.24780947109739737133;-0.23417264840334373055 0.1132386525167985436 1.1237751257497177182 0.61902092103360562003 0.47020551140138661106 0.34584873098241292189 1.0006855364955020704 -0.60628349280334392635 -0.26782427963571131535 0.26531233114408364626 -0.61882875127002012761 0.46929259170104825616 -0.89444636470801319739 -0.25830421778238343844 0.43771313985263160529;-0.19049385595377069103 -0.58938735606172598658 -0.30683905800424804422 0.28543302036623102724 -0.66476277571081976436 -0.50914248618552715442 0.53527439800527432112 0.29695993210007254337 -0.028450026139099540701 -0.20912115343947360047 0.13574909752244282424 -0.51843889260088116266 -0.39286302931711680753 -0.49857908811925044645 0.66646206078704595122;-0.76845175168381918418 -0.026432493658607947307 -0.45135598909654717215 0.18337122634838320945 0.27780414314587204005 0.62396658466391219378 0.14192752880526959824 0.35404119130304517737 1.2202300397735530435 -0.031665260435957742757 0.37157256775319902342 -0.74782560268609021836 0.63927427335464948044 -0.40671476611066503803 0.073776636400414541406;0.2733578142838976599 0.87370522119266114114 -0.45194664400177558816 -0.055352559306339067791 -0.61682085845030631965 0.59114819840785237659 0.018471933297485677861 -0.497152019807799328 -0.36184614758387634303 0.41929864177222075927 0.067615936447719432456 0.088059449863997746322 -0.14648786464482843606 -0.56007369226389402961 -0.81051016686766352848;-0.3018028529936557236 0.18518956333003830372 0.70275997482030116981 0.55474861005119691093 0.23764136942879379721 0.46862842130920928652 0.28033933834981716871 0.22629070148529978335 0.31546930512259580004 0.38475704170467173171 0.51255715927159528622 -0.51898140983705909335 -0.13177986827548068827 0.73966695419065875416 0.1800039745210262887];

% Output Layer
b3 = [-0.71491497362241662739;0.11422412561402123243];
W3_2 = [0.73970757042478618715 0.025662598571939376074 -0.25976007044713594896 0.49697777210645821544 0.69374621821921256259 -0.68083283559841001331 0.31865276538411319018 -0.85051994270445674395 -0.28025946760170994398 0.0010755204170892567438 -0.34912617443093296732 0.87400423961578188603 -0.39908076580884932483 0.31854047780026728542 -0.82061781655732224383;0.54370027897573125486 -0.44925035868345492007 0.30545011022459145344 0.95319693982727404791 0.49769828660919773755 -1.0324730092487834909 0.34033965525605919256 -0.75695619481777343118 -0.90158686449700542465 -0.33474080911511722158 -1.0875470258986148497 0.67732094010258758754 -0.8661505600372292335 -0.987764022497268801 -0.010908519804972517664];

% Output
y1_step1.ymin = -1;
y1_step1.gain = [1.91204588910134;1.806684733514];
y1_step1.xoffset = [0.111;0.199];

% ===== SIMULATION ========

% Dimensions
Q = size(x1,2); % samples

% Input 
xp1 = mapminmax_apply(x1,x1_step1);

% Hidden Layer 1 activation values array
a1 = tansig_apply(repmat(b1,1,Q) + W1_1*xp1);

% Hidden Layer 2 activation values array
a2 = tansig_apply(repmat(b2,1,Q) + W2_1*a1);

% Output Layer activation values array
a3 = repmat(b3,1,Q) + W3_2*a2;

% Output 
y1 = mapminmax_reverse(a3,y1_step1);
end

% ===== MODULE FUNCTIONS ========

% Map Minimum and Maximum Input Processing Function
function y = mapminmax_apply(x,settings)
  y = bsxfun(@minus,x,settings.xoffset);
  y = bsxfun(@times,y,settings.gain);
  y = bsxfun(@plus,y,settings.ymin);
end

% Sigmoid Symmetric Transfer Function
function a = tansig_apply(n,~)
  a = 2 ./ (1 + exp(-2*n)) - 1;
end

% Map Minimum and Maximum Output Reverse-Processing Function
function x = mapminmax_reverse(y,settings)
  x = bsxfun(@minus,y,settings.ymin);
  x = bsxfun(@rdivide,x,settings.gain);
  x = bsxfun(@plus,x,settings.xoffset);
end
