text:
using JuMP, EAGO

                     m = Model()

                     EAGO.register_eago_operators!(m)

                     @variable(m, -1 <= x[i=1:4] <= 1)

                     @variable(m, -51.708688423784224 <= q <= 53.49505517188359)

                     add_NL_constraint(m, :(swish(0.12651985253467002 + 0.8800990177661969*swish(0.9367289958343452 + 0.010085610540752743*swish(-0.5507415348587976 + -0.9382157052845588*$(x[1]) + 0.32792621601464056*$(x[2]) + 0.04402367930308282*$(x[3]) + 0.8348925442898456*$(x[4])) + -0.46191185446397043*swish(0.4569151270063867 + 0.9855428533575652*$(x[1]) + 0.27576336558204195*$(x[2]) + 0.024724286249658167*$(x[3]) + -0.4115946180479595*$(x[4])) + -0.4430556996324988*swish(0.5124722980797523 + -0.021522352811447654*$(x[1]) + 0.09961216478582813*$(x[2]) + -0.5936461652265081*$(x[3]) + 0.7973439553626904*$(x[4])) + 0.9244167282970754*swish(0.16894693163358276 + -0.35673489881937037*$(x[1]) + 0.5082818593140526*$(x[2]) + 0.7581208342644015*$(x[3]) + -0.6603822729791307*$(x[4])) + 0.15008923933940022*swish(-0.5086292355642796 + -0.9220327700183186*$(x[1]) + 0.16243082406428888*$(x[2]) + 0.7781879917830965*$(x[3]) + 0.45589624224566805*$(x[4]))) + 0.9059509477084742*swish(-0.9076856947519341 + 0.6427398296015978*swish(-0.5507415348587976 + -0.9382157052845588*$(x[1]) + 0.32792621601464056*$(x[2]) + 0.04402367930308282*$(x[3]) + 0.8348925442898456*$(x[4])) + 0.5974696839876872*swish(0.4569151270063867 + 0.9855428533575652*$(x[1]) + 0.27576336558204195*$(x[2]) + 0.024724286249658167*$(x[3]) + -0.4115946180479595*$(x[4])) + 0.3127996929073351*swish(0.5124722980797523 + -0.021522352811447654*$(x[1]) + 0.09961216478582813*$(x[2]) + -0.5936461652265081*$(x[3]) + 0.7973439553626904*$(x[4])) + 0.8921846648994118*swish(0.16894693163358276 + -0.35673489881937037*$(x[1]) + 0.5082818593140526*$(x[2]) + 0.7581208342644015*$(x[3]) + -0.6603822729791307*$(x[4])) + 0.8861141904898706*swish(-0.5086292355642796 + -0.9220327700183186*$(x[1]) + 0.16243082406428888*$(x[2]) + 0.7781879917830965*$(x[3]) + 0.45589624224566805*$(x[4]))) + 0.7662733112940292*swish(0.014219790982957559 + -0.1830460372609095*swish(-0.5507415348587976 + -0.9382157052845588*$(x[1]) + 0.32792621601464056*$(x[2]) + 0.04402367930308282*$(x[3]) + 0.8348925442898456*$(x[4])) + 0.18937048380167898*swish(0.4569151270063867 + 0.9855428533575652*$(x[1]) + 0.27576336558204195*$(x[2]) + 0.024724286249658167*$(x[3]) + -0.4115946180479595*$(x[4])) + -0.48856019606524415*swish(0.5124722980797523 + -0.021522352811447654*$(x[1]) + 0.09961216478582813*$(x[2]) + -0.5936461652265081*$(x[3]) + 0.7973439553626904*$(x[4])) + 0.6243584215460145*swish(0.16894693163358276 + -0.35673489881937037*$(x[1]) + 0.5082818593140526*$(x[2]) + 0.7581208342644015*$(x[3]) + -0.6603822729791307*$(x[4])) + -0.6378733350620909*swish(-0.5086292355642796 + -0.9220327700183186*$(x[1]) + 0.16243082406428888*$(x[2]) + 0.7781879917830965*$(x[3]) + 0.45589624224566805*$(x[4]))) + -0.3066544631255512*swish(0.37873800689777815 + 0.3786798527526116*swish(-0.5507415348587976 + -0.9382157052845588*$(x[1]) + 0.32792621601464056*$(x[2]) + 0.04402367930308282*$(x[3]) + 0.8348925442898456*$(x[4])) + -0.15214183164812667*swish(0.4569151270063867 + 0.9855428533575652*$(x[1]) + 0.27576336558204195*$(x[2]) + 0.024724286249658167*$(x[3]) + -0.4115946180479595*$(x[4])) + 0.4531653277321981*swish(0.5124722980797523 + -0.021522352811447654*$(x[1]) + 0.09961216478582813*$(x[2]) + -0.5936461652265081*$(x[3]) + 0.7973439553626904*$(x[4])) + -0.2698943947473773*swish(0.16894693163358276 + -0.35673489881937037*$(x[1]) + 0.5082818593140526*$(x[2]) + 0.7581208342644015*$(x[3]) + -0.6603822729791307*$(x[4])) + -0.8205030207972928*swish(-0.5086292355642796 + -0.9220327700183186*$(x[1]) + 0.16243082406428888*$(x[2]) + 0.7781879917830965*$(x[3]) + 0.45589624224566805*$(x[4]))) + 0.673637701918695*swish(0.41028851710489267 + 0.3789873528571355*swish(-0.5507415348587976 + -0.9382157052845588*$(x[1]) + 0.32792621601464056*$(x[2]) + 0.04402367930308282*$(x[3]) + 0.8348925442898456*$(x[4])) + -0.13395473418456794*swish(0.4569151270063867 + 0.9855428533575652*$(x[1]) + 0.27576336558204195*$(x[2]) + 0.024724286249658167*$(x[3]) + -0.4115946180479595*$(x[4])) + -0.9211828416113521*swish(0.5124722980797523 + -0.021522352811447654*$(x[1]) + 0.09961216478582813*$(x[2]) + -0.5936461652265081*$(x[3]) + 0.7973439553626904*$(x[4])) + 0.005265087561311166*swish(0.16894693163358276 + -0.35673489881937037*$(x[1]) + 0.5082818593140526*$(x[2]) + 0.7581208342644015*$(x[3]) + -0.6603822729791307*$(x[4])) + 0.6679558602332873*swish(-0.5086292355642796 + -0.9220327700183186*$(x[1]) + 0.16243082406428888*$(x[2]) + 0.7781879917830965*$(x[3]) + 0.45589624224566805*$(x[4])))) + swish(-0.8950204772394628 + -0.19603919659654778*swish(0.9367289958343452 + 0.010085610540752743*swish(-0.5507415348587976 + -0.9382157052845588*$(x[1]) + 0.32792621601464056*$(x[2]) + 0.04402367930308282*$(x[3]) + 0.8348925442898456*$(x[4])) + -0.46191185446397043*swish(0.4569151270063867 + 0.9855428533575652*$(x[1]) + 0.27576336558204195*$(x[2]) + 0.024724286249658167*$(x[3]) + -0.4115946180479595*$(x[4])) + -0.4430556996324988*swish(0.5124722980797523 + -0.021522352811447654*$(x[1]) + 0.09961216478582813*$(x[2]) + -0.5936461652265081*$(x[3]) + 0.7973439553626904*$(x[4])) + 0.9244167282970754*swish(0.16894693163358276 + -0.35673489881937037*$(x[1]) + 0.5082818593140526*$(x[2]) + 0.7581208342644015*$(x[3]) + -0.6603822729791307*$(x[4])) + 0.15008923933940022*swish(-0.5086292355642796 + -0.9220327700183186*$(x[1]) + 0.16243082406428888*$(x[2]) + 0.7781879917830965*$(x[3]) + 0.45589624224566805*$(x[4]))) + -0.902347490498435*swish(-0.9076856947519341 + 0.6427398296015978*swish(-0.5507415348587976 + -0.9382157052845588*$(x[1]) + 0.32792621601464056*$(x[2]) + 0.04402367930308282*$(x[3]) + 0.8348925442898456*$(x[4])) + 0.5974696839876872*swish(0.4569151270063867 + 0.9855428533575652*$(x[1]) + 0.27576336558204195*$(x[2]) + 0.024724286249658167*$(x[3]) + -0.4115946180479595*$(x[4])) + 0.3127996929073351*swish(0.5124722980797523 + -0.021522352811447654*$(x[1]) + 0.09961216478582813*$(x[2]) + -0.5936461652265081*$(x[3]) + 0.7973439553626904*$(x[4])) + 0.8921846648994118*swish(0.16894693163358276 + -0.35673489881937037*$(x[1]) + 0.5082818593140526*$(x[2]) + 0.7581208342644015*$(x[3]) + -0.6603822729791307*$(x[4])) + 0.8861141904898706*swish(-0.5086292355642796 + -0.9220327700183186*$(x[1]) + 0.16243082406428888*$(x[2]) + 0.7781879917830965*$(x[3]) + 0.45589624224566805*$(x[4]))) + -0.30440629677970144*swish(0.014219790982957559 + -0.1830460372609095*swish(-0.5507415348587976 + -0.9382157052845588*$(x[1]) + 0.32792621601464056*$(x[2]) + 0.04402367930308282*$(x[3]) + 0.8348925442898456*$(x[4])) + 0.18937048380167898*swish(0.4569151270063867 + 0.9855428533575652*$(x[1]) + 0.27576336558204195*$(x[2]) + 0.024724286249658167*$(x[3]) + -0.4115946180479595*$(x[4])) + -0.48856019606524415*swish(0.5124722980797523 + -0.021522352811447654*$(x[1]) + 0.09961216478582813*$(x[2]) + -0.5936461652265081*$(x[3]) + 0.7973439553626904*$(x[4])) + 0.6243584215460145*swish(0.16894693163358276 + -0.35673489881937037*$(x[1]) + 0.5082818593140526*$(x[2]) + 0.7581208342644015*$(x[3]) + -0.6603822729791307*$(x[4])) + -0.6378733350620909*swish(-0.5086292355642796 + -0.9220327700183186*$(x[1]) + 0.16243082406428888*$(x[2]) + 0.7781879917830965*$(x[3]) + 0.45589624224566805*$(x[4]))) + 0.6770808003403048*swish(0.37873800689777815 + 0.3786798527526116*swish(-0.5507415348587976 + -0.9382157052845588*$(x[1]) + 0.32792621601464056*$(x[2]) + 0.04402367930308282*$(x[3]) + 0.8348925442898456*$(x[4])) + -0.15214183164812667*swish(0.4569151270063867 + 0.9855428533575652*$(x[1]) + 0.27576336558204195*$(x[2]) + 0.024724286249658167*$(x[3]) + -0.4115946180479595*$(x[4])) + 0.4531653277321981*swish(0.5124722980797523 + -0.021522352811447654*$(x[1]) + 0.09961216478582813*$(x[2]) + -0.5936461652265081*$(x[3]) + 0.7973439553626904*$(x[4])) + -0.2698943947473773*swish(0.16894693163358276 + -0.35673489881937037*$(x[1]) + 0.5082818593140526*$(x[2]) + 0.7581208342644015*$(x[3]) + -0.6603822729791307*$(x[4])) + -0.8205030207972928*swish(-0.5086292355642796 + -0.9220327700183186*$(x[1]) + 0.16243082406428888*$(x[2]) + 0.7781879917830965*$(x[3]) + 0.45589624224566805*$(x[4]))) + 0.03232239144278681*swish(0.41028851710489267 + 0.3789873528571355*swish(-0.5507415348587976 + -0.9382157052845588*$(x[1]) + 0.32792621601464056*$(x[2]) + 0.04402367930308282*$(x[3]) + 0.8348925442898456*$(x[4])) + -0.13395473418456794*swish(0.4569151270063867 + 0.9855428533575652*$(x[1]) + 0.27576336558204195*$(x[2]) + 0.024724286249658167*$(x[3]) + -0.4115946180479595*$(x[4])) + -0.9211828416113521*swish(0.5124722980797523 + -0.021522352811447654*$(x[1]) + 0.09961216478582813*$(x[2]) + -0.5936461652265081*$(x[3]) + 0.7973439553626904*$(x[4])) + 0.005265087561311166*swish(0.16894693163358276 + -0.35673489881937037*$(x[1]) + 0.5082818593140526*$(x[2]) + 0.7581208342644015*$(x[3]) + -0.6603822729791307*$(x[4])) + 0.6679558602332873*swish(-0.5086292355642796 + -0.9220327700183186*$(x[1]) + 0.16243082406428888*$(x[2]) + 0.7781879917830965*$(x[3]) + 0.45589624224566805*$(x[4])))) + swish(-0.11076390433121786 + 0.7661103402200116*swish(0.9367289958343452 + 0.010085610540752743*swish(-0.5507415348587976 + -0.9382157052845588*$(x[1]) + 0.32792621601464056*$(x[2]) + 0.04402367930308282*$(x[3]) + 0.8348925442898456*$(x[4])) + -0.46191185446397043*swish(0.4569151270063867 + 0.9855428533575652*$(x[1]) + 0.27576336558204195*$(x[2]) + 0.024724286249658167*$(x[3]) + -0.4115946180479595*$(x[4])) + -0.4430556996324988*swish(0.5124722980797523 + -0.021522352811447654*$(x[1]) + 0.09961216478582813*$(x[2]) + -0.5936461652265081*$(x[3]) + 0.7973439553626904*$(x[4])) + 0.9244167282970754*swish(0.16894693163358276 + -0.35673489881937037*$(x[1]) + 0.5082818593140526*$(x[2]) + 0.7581208342644015*$(x[3]) + -0.6603822729791307*$(x[4])) + 0.15008923933940022*swish(-0.5086292355642796 + -0.9220327700183186*$(x[1]) + 0.16243082406428888*$(x[2]) + 0.7781879917830965*$(x[3]) + 0.45589624224566805*$(x[4]))) + -0.9009199905889229*swish(-0.9076856947519341 + 0.6427398296015978*swish(-0.5507415348587976 + -0.9382157052845588*$(x[1]) + 0.32792621601464056*$(x[2]) + 0.04402367930308282*$(x[3]) + 0.8348925442898456*$(x[4])) + 0.5974696839876872*swish(0.4569151270063867 + 0.9855428533575652*$(x[1]) + 0.27576336558204195*$(x[2]) + 0.024724286249658167*$(x[3]) + -0.4115946180479595*$(x[4])) + 0.3127996929073351*swish(0.5124722980797523 + -0.021522352811447654*$(x[1]) + 0.09961216478582813*$(x[2]) + -0.5936461652265081*$(x[3]) + 0.7973439553626904*$(x[4])) + 0.8921846648994118*swish(0.16894693163358276 + -0.35673489881937037*$(x[1]) + 0.5082818593140526*$(x[2]) + 0.7581208342644015*$(x[3]) + -0.6603822729791307*$(x[4])) + 0.8861141904898706*swish(-0.5086292355642796 + -0.9220327700183186*$(x[1]) + 0.16243082406428888*$(x[2]) + 0.7781879917830965*$(x[3]) + 0.45589624224566805*$(x[4]))) + 0.5631507797475948*swish(0.014219790982957559 + -0.1830460372609095*swish(-0.5507415348587976 + -0.9382157052845588*$(x[1]) + 0.32792621601464056*$(x[2]) + 0.04402367930308282*$(x[3]) + 0.8348925442898456*$(x[4])) + 0.18937048380167898*swish(0.4569151270063867 + 0.9855428533575652*$(x[1]) + 0.27576336558204195*$(x[2]) + 0.024724286249658167*$(x[3]) + -0.4115946180479595*$(x[4])) + -0.48856019606524415*swish(0.5124722980797523 + -0.021522352811447654*$(x[1]) + 0.09961216478582813*$(x[2]) + -0.5936461652265081*$(x[3]) + 0.7973439553626904*$(x[4])) + 0.6243584215460145*swish(0.16894693163358276 + -0.35673489881937037*$(x[1]) + 0.5082818593140526*$(x[2]) + 0.7581208342644015*$(x[3]) + -0.6603822729791307*$(x[4])) + -0.6378733350620909*swish(-0.5086292355642796 + -0.9220327700183186*$(x[1]) + 0.16243082406428888*$(x[2]) + 0.7781879917830965*$(x[3]) + 0.45589624224566805*$(x[4]))) + -0.4163802251888926*swish(0.37873800689777815 + 0.3786798527526116*swish(-0.5507415348587976 + -0.9382157052845588*$(x[1]) + 0.32792621601464056*$(x[2]) + 0.04402367930308282*$(x[3]) + 0.8348925442898456*$(x[4])) + -0.15214183164812667*swish(0.4569151270063867 + 0.9855428533575652*$(x[1]) + 0.27576336558204195*$(x[2]) + 0.024724286249658167*$(x[3]) + -0.4115946180479595*$(x[4])) + 0.4531653277321981*swish(0.5124722980797523 + -0.021522352811447654*$(x[1]) + 0.09961216478582813*$(x[2]) + -0.5936461652265081*$(x[3]) + 0.7973439553626904*$(x[4])) + -0.2698943947473773*swish(0.16894693163358276 + -0.35673489881937037*$(x[1]) + 0.5082818593140526*$(x[2]) + 0.7581208342644015*$(x[3]) + -0.6603822729791307*$(x[4])) + -0.8205030207972928*swish(-0.5086292355642796 + -0.9220327700183186*$(x[1]) + 0.16243082406428888*$(x[2]) + 0.7781879917830965*$(x[3]) + 0.45589624224566805*$(x[4]))) + -0.17662226846197893*swish(0.41028851710489267 + 0.3789873528571355*swish(-0.5507415348587976 + -0.9382157052845588*$(x[1]) + 0.32792621601464056*$(x[2]) + 0.04402367930308282*$(x[3]) + 0.8348925442898456*$(x[4])) + -0.13395473418456794*swish(0.4569151270063867 + 0.9855428533575652*$(x[1]) + 0.27576336558204195*$(x[2]) + 0.024724286249658167*$(x[3]) + -0.4115946180479595*$(x[4])) + -0.9211828416113521*swish(0.5124722980797523 + -0.021522352811447654*$(x[1]) + 0.09961216478582813*$(x[2]) + -0.5936461652265081*$(x[3]) + 0.7973439553626904*$(x[4])) + 0.005265087561311166*swish(0.16894693163358276 + -0.35673489881937037*$(x[1]) + 0.5082818593140526*$(x[2]) + 0.7581208342644015*$(x[3]) + -0.6603822729791307*$(x[4])) + 0.6679558602332873*swish(-0.5086292355642796 + -0.9220327700183186*$(x[1]) + 0.16243082406428888*$(x[2]) + 0.7781879917830965*$(x[3]) + 0.45589624224566805*$(x[4])))) + swish(0.8242960442017702 + -0.7506191216499181*swish(0.9367289958343452 + 0.010085610540752743*swish(-0.5507415348587976 + -0.9382157052845588*$(x[1]) + 0.32792621601464056*$(x[2]) + 0.04402367930308282*$(x[3]) + 0.8348925442898456*$(x[4])) + -0.46191185446397043*swish(0.4569151270063867 + 0.9855428533575652*$(x[1]) + 0.27576336558204195*$(x[2]) + 0.024724286249658167*$(x[3]) + -0.4115946180479595*$(x[4])) + -0.4430556996324988*swish(0.5124722980797523 + -0.021522352811447654*$(x[1]) + 0.09961216478582813*$(x[2]) + -0.5936461652265081*$(x[3]) + 0.7973439553626904*$(x[4])) + 0.9244167282970754*swish(0.16894693163358276 + -0.35673489881937037*$(x[1]) + 0.5082818593140526*$(x[2]) + 0.7581208342644015*$(x[3]) + -0.6603822729791307*$(x[4])) + 0.15008923933940022*swish(-0.5086292355642796 + -0.9220327700183186*$(x[1]) + 0.16243082406428888*$(x[2]) + 0.7781879917830965*$(x[3]) + 0.45589624224566805*$(x[4]))) + 0.31521888864028513*swish(-0.9076856947519341 + 0.6427398296015978*swish(-0.5507415348587976 + -0.9382157052845588*$(x[1]) + 0.32792621601464056*$(x[2]) + 0.04402367930308282*$(x[3]) + 0.8348925442898456*$(x[4])) + 0.5974696839876872*swish(0.4569151270063867 + 0.9855428533575652*$(x[1]) + 0.27576336558204195*$(x[2]) + 0.024724286249658167*$(x[3]) + -0.4115946180479595*$(x[4])) + 0.3127996929073351*swish(0.5124722980797523 + -0.021522352811447654*$(x[1]) + 0.09961216478582813*$(x[2]) + -0.5936461652265081*$(x[3]) + 0.7973439553626904*$(x[4])) + 0.8921846648994118*swish(0.16894693163358276 + -0.35673489881937037*$(x[1]) + 0.5082818593140526*$(x[2]) + 0.7581208342644015*$(x[3]) + -0.6603822729791307*$(x[4])) + 0.8861141904898706*swish(-0.5086292355642796 + -0.9220327700183186*$(x[1]) + 0.16243082406428888*$(x[2]) + 0.7781879917830965*$(x[3]) + 0.45589624224566805*$(x[4]))) + 0.5308637261158768*swish(0.014219790982957559 + -0.1830460372609095*swish(-0.5507415348587976 + -0.9382157052845588*$(x[1]) + 0.32792621601464056*$(x[2]) + 0.04402367930308282*$(x[3]) + 0.8348925442898456*$(x[4])) + 0.18937048380167898*swish(0.4569151270063867 + 0.9855428533575652*$(x[1]) + 0.27576336558204195*$(x[2]) + 0.024724286249658167*$(x[3]) + -0.4115946180479595*$(x[4])) + -0.48856019606524415*swish(0.5124722980797523 + -0.021522352811447654*$(x[1]) + 0.09961216478582813*$(x[2]) + -0.5936461652265081*$(x[3]) + 0.7973439553626904*$(x[4])) + 0.6243584215460145*swish(0.16894693163358276 + -0.35673489881937037*$(x[1]) + 0.5082818593140526*$(x[2]) + 0.7581208342644015*$(x[3]) + -0.6603822729791307*$(x[4])) + -0.6378733350620909*swish(-0.5086292355642796 + -0.9220327700183186*$(x[1]) + 0.16243082406428888*$(x[2]) + 0.7781879917830965*$(x[3]) + 0.45589624224566805*$(x[4]))) + -0.6654841763336146*swish(0.37873800689777815 + 0.3786798527526116*swish(-0.5507415348587976 + -0.9382157052845588*$(x[1]) + 0.32792621601464056*$(x[2]) + 0.04402367930308282*$(x[3]) + 0.8348925442898456*$(x[4])) + -0.15214183164812667*swish(0.4569151270063867 + 0.9855428533575652*$(x[1]) + 0.27576336558204195*$(x[2]) + 0.024724286249658167*$(x[3]) + -0.4115946180479595*$(x[4])) + 0.4531653277321981*swish(0.5124722980797523 + -0.021522352811447654*$(x[1]) + 0.09961216478582813*$(x[2]) + -0.5936461652265081*$(x[3]) + 0.7973439553626904*$(x[4])) + -0.2698943947473773*swish(0.16894693163358276 + -0.35673489881937037*$(x[1]) + 0.5082818593140526*$(x[2]) + 0.7581208342644015*$(x[3]) + -0.6603822729791307*$(x[4])) + -0.8205030207972928*swish(-0.5086292355642796 + -0.9220327700183186*$(x[1]) + 0.16243082406428888*$(x[2]) + 0.7781879917830965*$(x[3]) + 0.45589624224566805*$(x[4]))) + 0.2645412007156045*swish(0.41028851710489267 + 0.3789873528571355*swish(-0.5507415348587976 + -0.9382157052845588*$(x[1]) + 0.32792621601464056*$(x[2]) + 0.04402367930308282*$(x[3]) + 0.8348925442898456*$(x[4])) + -0.13395473418456794*swish(0.4569151270063867 + 0.9855428533575652*$(x[1]) + 0.27576336558204195*$(x[2]) + 0.024724286249658167*$(x[3]) + -0.4115946180479595*$(x[4])) + -0.9211828416113521*swish(0.5124722980797523 + -0.021522352811447654*$(x[1]) + 0.09961216478582813*$(x[2]) + -0.5936461652265081*$(x[3]) + 0.7973439553626904*$(x[4])) + 0.005265087561311166*swish(0.16894693163358276 + -0.35673489881937037*$(x[1]) + 0.5082818593140526*$(x[2]) + 0.7581208342644015*$(x[3]) + -0.6603822729791307*$(x[4])) + 0.6679558602332873*swish(-0.5086292355642796 + -0.9220327700183186*$(x[1]) + 0.16243082406428888*$(x[2]) + 0.7781879917830965*$(x[3]) + 0.45589624224566805*$(x[4])))) + swish(-0.6657453597374303 + 0.46323784626870257*swish(0.9367289958343452 + 0.010085610540752743*swish(-0.5507415348587976 + -0.9382157052845588*$(x[1]) + 0.32792621601464056*$(x[2]) + 0.04402367930308282*$(x[3]) + 0.8348925442898456*$(x[4])) + -0.46191185446397043*swish(0.4569151270063867 + 0.9855428533575652*$(x[1]) + 0.27576336558204195*$(x[2]) + 0.024724286249658167*$(x[3]) + -0.4115946180479595*$(x[4])) + -0.4430556996324988*swish(0.5124722980797523 + -0.021522352811447654*$(x[1]) + 0.09961216478582813*$(x[2]) + -0.5936461652265081*$(x[3]) + 0.7973439553626904*$(x[4])) + 0.9244167282970754*swish(0.16894693163358276 + -0.35673489881937037*$(x[1]) + 0.5082818593140526*$(x[2]) + 0.7581208342644015*$(x[3]) + -0.6603822729791307*$(x[4])) + 0.15008923933940022*swish(-0.5086292355642796 + -0.9220327700183186*$(x[1]) + 0.16243082406428888*$(x[2]) + 0.7781879917830965*$(x[3]) + 0.45589624224566805*$(x[4]))) + 0.7128966868012561*swish(-0.9076856947519341 + 0.6427398296015978*swish(-0.5507415348587976 + -0.9382157052845588*$(x[1]) + 0.32792621601464056*$(x[2]) + 0.04402367930308282*$(x[3]) + 0.8348925442898456*$(x[4])) + 0.5974696839876872*swish(0.4569151270063867 + 0.9855428533575652*$(x[1]) + 0.27576336558204195*$(x[2]) + 0.024724286249658167*$(x[3]) + -0.4115946180479595*$(x[4])) + 0.3127996929073351*swish(0.5124722980797523 + -0.021522352811447654*$(x[1]) + 0.09961216478582813*$(x[2]) + -0.5936461652265081*$(x[3]) + 0.7973439553626904*$(x[4])) + 0.8921846648994118*swish(0.16894693163358276 + -0.35673489881937037*$(x[1]) + 0.5082818593140526*$(x[2]) + 0.7581208342644015*$(x[3]) + -0.6603822729791307*$(x[4])) + 0.8861141904898706*swish(-0.5086292355642796 + -0.9220327700183186*$(x[1]) + 0.16243082406428888*$(x[2]) + 0.7781879917830965*$(x[3]) + 0.45589624224566805*$(x[4]))) + 0.43240821263487783*swish(0.014219790982957559 + -0.1830460372609095*swish(-0.5507415348587976 + -0.9382157052845588*$(x[1]) + 0.32792621601464056*$(x[2]) + 0.04402367930308282*$(x[3]) + 0.8348925442898456*$(x[4])) + 0.18937048380167898*swish(0.4569151270063867 + 0.9855428533575652*$(x[1]) + 0.27576336558204195*$(x[2]) + 0.024724286249658167*$(x[3]) + -0.4115946180479595*$(x[4])) + -0.48856019606524415*swish(0.5124722980797523 + -0.021522352811447654*$(x[1]) + 0.09961216478582813*$(x[2]) + -0.5936461652265081*$(x[3]) + 0.7973439553626904*$(x[4])) + 0.6243584215460145*swish(0.16894693163358276 + -0.35673489881937037*$(x[1]) + 0.5082818593140526*$(x[2]) + 0.7581208342644015*$(x[3]) + -0.6603822729791307*$(x[4])) + -0.6378733350620909*swish(-0.5086292355642796 + -0.9220327700183186*$(x[1]) + 0.16243082406428888*$(x[2]) + 0.7781879917830965*$(x[3]) + 0.45589624224566805*$(x[4]))) + -0.6998749584965918*swish(0.37873800689777815 + 0.3786798527526116*swish(-0.5507415348587976 + -0.9382157052845588*$(x[1]) + 0.32792621601464056*$(x[2]) + 0.04402367930308282*$(x[3]) + 0.8348925442898456*$(x[4])) + -0.15214183164812667*swish(0.4569151270063867 + 0.9855428533575652*$(x[1]) + 0.27576336558204195*$(x[2]) + 0.024724286249658167*$(x[3]) + -0.4115946180479595*$(x[4])) + 0.4531653277321981*swish(0.5124722980797523 + -0.021522352811447654*$(x[1]) + 0.09961216478582813*$(x[2]) + -0.5936461652265081*$(x[3]) + 0.7973439553626904*$(x[4])) + -0.2698943947473773*swish(0.16894693163358276 + -0.35673489881937037*$(x[1]) + 0.5082818593140526*$(x[2]) + 0.7581208342644015*$(x[3]) + -0.6603822729791307*$(x[4])) + -0.8205030207972928*swish(-0.5086292355642796 + -0.9220327700183186*$(x[1]) + 0.16243082406428888*$(x[2]) + 0.7781879917830965*$(x[3]) + 0.45589624224566805*$(x[4]))) + 0.6177298271304656*swish(0.41028851710489267 + 0.3789873528571355*swish(-0.5507415348587976 + -0.9382157052845588*$(x[1]) + 0.32792621601464056*$(x[2]) + 0.04402367930308282*$(x[3]) + 0.8348925442898456*$(x[4])) + -0.13395473418456794*swish(0.4569151270063867 + 0.9855428533575652*$(x[1]) + 0.27576336558204195*$(x[2]) + 0.024724286249658167*$(x[3]) + -0.4115946180479595*$(x[4])) + -0.9211828416113521*swish(0.5124722980797523 + -0.021522352811447654*$(x[1]) + 0.09961216478582813*$(x[2]) + -0.5936461652265081*$(x[3]) + 0.7973439553626904*$(x[4])) + 0.005265087561311166*swish(0.16894693163358276 + -0.35673489881937037*$(x[1]) + 0.5082818593140526*$(x[2]) + 0.7581208342644015*$(x[3]) + -0.6603822729791307*$(x[4])) + 0.6679558602332873*swish(-0.5086292355642796 + -0.9220327700183186*$(x[1]) + 0.16243082406428888*$(x[2]) + 0.7781879917830965*$(x[3]) + 0.45589624224566805*$(x[4])))) - $q <= 0.0))

                     @objective(m, Min, q)

                     return m

max_stars_repo_name: PSORLab/RSActivationFunctions

max_issues_repo_name: PSORLab/RSActivationFunctions

max_forks_repo_name: PSORLab/RSActivationFunctions


text:
# Primal infeasible test problems
# x >= 0, elements in A >=0, elements in b <0 and s in R+

nn = 1
rng = Random.MersenneTwister(74747)

@testset "Primal infeasible QP problems - Testset 1" begin
  for iii = 1:nn

    # choose size of problem
    n = rand(rng, 5:50)
    m = 2 * n
    A = sprand(rng, m, n, 0.8)
    b = -rand(rng, m)
    A = [A; -sparse(1.0I, n, n)]
    b = [b; zeros(n)]

    # create dual feasible problem
    P = generate_pos_def_matrix(n, rng)
    ytrue = rand(rng, m + n, 1)
    xtrue = rand(rng, n, 1)
    q = (-P * xtrue -  A' * ytrue)[:]

    constraint = COSMO.Constraint(-A, b, COSMO.Nonnegatives)
    ra = 0.

    settings = COSMO.Settings(max_iter=10000, eps_abs = 1e-5, eps_rel=1e-5)
    model = COSMO.Model()
    assemble!(model, P, q, constraint, settings = settings)
    res1 = COSMO.optimize!(model);

     @test res1.status == :Primal_infeasible
  end
end
nothing

ext: jl


text:
"""
    MultivariateTimeSeries

A package for storing and working with heterogeneous multivariate time series datasets.
"""
module MultivariateTimeSeries

using Random
using ZipFile
using Reexport
@reexport using DataFrames
using DataFrames: printtable
using CSV

export
        MTS,
        has_labels,
        read_data,
        read_data_labeled,
        write_data,
        normalize01,
        append_stop_token,
        test_mts,
        trim,
        transform,
        transform_cols

const METAFILE = "_meta.txt"
const DATAFILE = "data.csv.gz"
const LABELFILE = "labels.txt"

"""
    MTS

Multivariate time series data.
"""
struct MTS <: AbstractVector{SubDataFrame}
    data::DataFrame
    index::Vector{Int}
    views::Vector{SubDataFrame}
end

"""
    MTS(data::DataFrame, index::Vector{Int})

Create MTS object from a merged dataframe data and index containing the start indices of each record.
"""
function MTS(data::DataFrame, index::Vector{Int})
    views = Vector{SubDataFrame}(undef,length(index))
    for i in eachindex(index)
        start_ind, end_ind = index[i], end_index(i, data, index)
        views[i] = view(data, start_ind:end_ind, :)
    end
    MTS(data, index, views)
end
"""
    MTS(v::AbstractVector{T}) where {T<:AbstractDataFrame}

Create MTS object from a vector of DataFrames.  All dataframes must contain the same fields.
"""
function MTS(v::AbstractVector{T}) where {T<:AbstractDataFrame}
    index_ = cumsum([nrow(d) for d in v]) .+ 1
    index = [1; index_[1:end-1]]
    data = vcat(v...)
    MTS(data, index)
end
"""
    MTS(mts::MTS, inds::UnitRange{Int})

Create MTS object from mts using only data at inds.
"""
MTS(mts::MTS, inds::UnitRange{Int}) = MTS(mts[inds])

"""
    end_index(i::Int, d::DataFrame, index::AbstractVector{Int})

Returns the end index of a record for index i.
"""
function end_index(i::Int, d::DataFrame, index::AbstractVector{Int})
    i+1 ≤ length(index) ? index[i+1]-1 : nrow(d)
end

"""
    Zip

Data is stored in a zip file
"""
struct Zip
    path::String
    Zip(f::String) = endswith(f, ".zip") ? new(f) : new("$f.zip")
end
"""
    Dir

Data is stored in a directory
"""
struct Dir
    path::String
    Dir(p::String) = new(abspath(p))
end

"""
    read_data(path::AbstractString)

Load and return a dataset.  Automatically detects the source type based on the given path.
"""
function read_data(path::AbstractString)
    if isdir(path)
        return read_data(Dir(path))
    else
        return read_data(Zip(path))
    end
end
"""
    read_data_labeled(path::AbstractString)

Load and return a labeled dataset as a tuple (data, labels)
"""
function read_data_labeled(path::AbstractString)
    if isdir(path)
        return read_data_labeled(Dir(path))
    else
        return read_data_labeled(Zip(path))
    end
end
"""
    read_data(z::Zip)

Load and return a dataset from a zip file.
"""
function read_data(z::Zip)
    r = ZipFile.Reader(z.path)

    d = Dict{String,ZipFile.ReadableFile}()
    for f in r.files
        d[f.name] = f
    end

    index = read_meta(d[METAFILE])
    data = CSV.File(read(d[DATAFILE])) |> DataFrame

    close(r)
    return MTS(data, index)
end
"""
    read_data_labeled(z::Zip)

Load and return a labeled dataset from a zip file.  Returns a tuple (data, labels)
"""
function read_data_labeled(z::Zip)
    r = ZipFile.Reader(z.path)

    d = Dict{String,ZipFile.ReadableFile}()
    for f in r.files
        d[f.name] = f
    end

    index = read_meta(read(d[METAFILE]))
    data = CSV.File(read(d[DATAFILE])) |> DataFrame

    labels = nothing
    if haskey(d, LABELFILE)
        labels = read_labels(d[LABELFILE])
    end
    close(r)
    return (MTS(data, index), labels)
end
"""
    read_data(d::Dir)

Load and return a dataset from a directory.
"""
function read_data(d::Dir)
    f_meta = open(joinpath(d.path, METAFILE))
    index = read_meta(f_meta)
    close(f_meta)

    data = CSV.File(joinpath(d.path, DATAFILE)) |> DataFrame

    return MTS(data, index)
end
"""
    read_data_labeled(d::Dir)

Load and return a labeled dataset from a directory.  Returns a tuple (data, labels).
"""
function read_data_labeled(d::Dir)
    f_meta = open(joinpath(d.path, METAFILE))
    index = read_meta(f_meta)
    close(f_meta)

    data = CSV.File(joinpath(d.path, DATAFILE)) |> DataFrame

    labels = nothing
    if isfile(joinpath(d.path, LABELFILE))
        f_label = open(joinpath(d.path, LABELFILE))
        labels = read_labels(f_label)
        close(f_label)
    end
    return (MTS(data, index), labels)
end
"""
    read_meta(io::IO)

Read and parse dataset meta file.
"""
function read_meta(io::IO)
    s = read(io,String)
    toks = split(s, ","; keepempty=false) #line1: indices
    index = Base.parse.(Int, toks)
    index
end
read_meta(v::Vector{UInt8}) = IOBuffer(v) |> read_meta

"""
    read_labels(io::IO)

Read and parse dataset labels file.
"""
function read_labels(io::IO)
    typ = eval(Meta.parse(readline(io))) #line1: eltype
    labels = split(readline(io), ",") #line2: labels
    if typ in [Bool, Int, Int32, Int64, Float32, Float64]
        labels = Base.parse.(typ, labels)
    elseif typ == Symbol
        labels = Symbol.(labels)
    else #fall back on convert
        labels = convert(Vector{typ}, labels)
    end
    labels
end

"""
    has_labels(path::AbstractString)

Returns true if dataset at path contains labels.
"""
function has_labels(path::AbstractString)
    if isdir(path)
        return has_labels(Dir(path))
    else
        return has_labels(Zip(path))
    end
end
"""
    has_labels(z::Zip)

Returns true if dataset in zipfile contains labels.
"""
function has_labels(z::Zip)
    r = ZipFile.Reader(z.path)
    retval = LABELFILE in r
    close(r)
    retval
end
"""
   has_labels(d::Dir)

Returns true if dataset in directory contains labels.
"""
has_labels(d::Dir) = isfile(joinpath(d.path, LABELFILE))

"""
    write_data(zipfile::AbstractString, mts::MTS, labels::AbstractVector{T}=Int[]) where T

Write data to file.  Optionally, include labels.
"""
function write_data(zipfile::AbstractString, mts::MTS, labels::AbstractVector{T}=Int[]) where T
    w = ZipFile.Writer(zipfile)

    f_meta = ZipFile.addfile(w, METAFILE)
    write_meta(f_meta, mts)

    f_data = ZipFile.addfile(w, DATAFILE)
    printtable(f_data, mts.data)

    if !isempty(labels)
        f_labels = ZipFile.addfile(w, LABELFILE)
        write_labels(f_labels, labels)
    end

    close(w)
end
"""
    write_meta(io::IO, mts::MTS)

Write meta file.
"""
function write_meta(io::IO, mts::MTS)
    println(io, join(mts.index, ","))
end
"""
    write_labels(io::IO, labels::AbstractVector{T}) where T

Write labels file.
"""
function write_labels(io::IO, labels::AbstractVector{T}) where T
    println(io, T)
    println(io, join(labels, ","))
end

"""
    Base.in(file::AbstractString, r::ZipFile.Reader)

Returns true if zipfile contains file.
"""
function Base.in(file::AbstractString, r::ZipFile.Reader)
    file in [f.name for f in r.files]
end

"""
    Base.open(r::ZipFile.Reader, file::AbstractString)

Returns file handle of file from zipfile.
"""
function Base.open(r::ZipFile.Reader, file::AbstractString)
    i = something(findfirst(isequal(file), [f.name for f in r.files]), 0)
    i > 0 || error("File not found: $file")
    return r.files[i]
end

"""
    getindex(mts::MTS, i::Int)

Returns the i'th record of the data.
"""
Base.getindex(mts::MTS, i::Int) = mts.views[i]

"""
    length(mts::MTS)

Returns the number of records in the dataset.
"""
Base.length(mts::MTS) = length(mts.views)

#iterate over all records in dataset
function Base.iterate(mts::MTS)
    return (length(mts) > 0) ? (mts.views[1], 2) : nothing
end
function Base.iterate(mts::MTS, i::Int)
    return (i > length(mts)) ? nothing : (mts.views[i], i+1)
end
function Base.:(==)(mts1::MTS, mts2::MTS)
    mts1.data == mts2.data
    mts1.index == mts2.index
    mts1.views == mts2.views
end

"""
    Base.names(mts::MTS)

Returns the feature names of the data.
"""
Base.names(mts::MTS) = names(mts.data)

"""
    Base.size(mts::MTS)

Returns the number of records in the dataset as a tuple
"""
Base.size(mts::MTS) = (length(mts),)

"""
    Base.minimum(mts::MTS, sym::Symbol)

Returns the minimum value over all records for feature sym.
"""
Base.minimum(mts::MTS, sym::Symbol) = minimum(mts.data[!,sym])
"""
    Base.minimum(mts::MTS)

Returns the minimum values over all records for each feature.
"""
Base.minimum(mts::MTS) = [minimum(mts.data[!,s]) for s in names(mts)]
"""
    Base.maximum(mts::MTS, sym::Symbol)

Returns the maximum value over all records for feature sym.
"""
Base.maximum(mts::MTS, sym::Symbol) = maximum(mts.data[!,sym])
"""
    Base.maximum(mts::MTS)

Returns the maximum values over all records for each feature.
"""
Base.maximum(mts::MTS) = [maximum(mts.data[!,s]) for s in names(mts)]
"""
    normalize01(mts::MTS)

Returns a new mts where each column is rescaled to [0,1].
"""
function normalize01(mts::MTS; fillval::Float64=0.5)
    mts1 = deepcopy(mts)
    mins, maxes = minimum(mts), maximum(mts)
    @assert length(mins) == length(maxes)
    for i = 1:length(mins)
        d = maxes[i] - mins[i]
        mts1.data[!,i] = iszero(d) ? fill(fillval, nrow(mts1.data[!,i])) : (mts1.data[!,i] .- mins[i]) ./ d
    end
    mts1
end
"""
    DataFrames.ncol(mts::MTS)

Returns the number of features in the dataset.
"""
DataFrames.ncol(mts::MTS) = ncol(mts.data)

function Base.vcat(m1::MTS, ms::MTS...)
    offsets = vcat(nrow(m1.data), [nrow(m.data) for m in ms]...)[1:end-1] |> cumsum
    data = vcat(m1.data, [m.data for m in ms]...)
    index = vcat(m1.index, [m.index.+o for (m,o) in zip(ms,offsets)]...)
    MTS(data, index)
end

"""
    vec(mts::MTS)

Convert to vec of vec of vec representation.  Some ML packages, e.g., Flux.jl, use this format.
"""
function Base.vec(mts::MTS)
    [vec(mts,i) for i=1:length(mts)]
end
function Base.vec(mts::MTS, i::Int)
    A = convert(Array{Float64,2}, mts[i])
    [A[i,:] for i in 1:size(A,1)]
end

"""
    append_stop_token(mts::MTS)

Add a stop token column that is only true at the end of a sequence. Token type T.
"""
function append_stop_token(mts::MTS; T=Float64, colname=:stop)
    #update data
    V = []
    for i in eachindex(mts.index)
        start_ind, end_ind = mts.index[i], end_index(i, mts.data, mts.index)
        d = mts.data[start_ind:end_ind,:]
        d[colname] = zero(T)
        push!(d, fill(zero(T), ncol(d)))
        d[end, end] = one(T)
        push!(V, d)
    end
    data = vcat(V...)
    index = [mts.index[i]+(i-1) for i=1:length(mts.index)]
    MTS(data, index)
end
"""
    Base.repeat(mts::MTS, N::Int)

Stack mts vertically N times.
"""
Base.repeat(mts::MTS, N::Int) = foldl(vcat, mts for i=1:N)

"""
    Base.findfirst(f::Function, df::AbstractDataFrame)

Find the first row of the dataframe df where f is true.  Returns 0 if not found.
"""
function Base.findfirst(f::Function, df::AbstractDataFrame)
    i = 1
    for r in eachrow(df)
        f(r) && return i
        i += 1
    end
    return 0
end
"""
    Base.findfirst(f::Function, mts::MTS)

Apply findfirst to each dataframe in mts returning a vector of integers that indicate the first row where findfirst is true.
"""
Base.findfirst(f::Function, mts::MTS) = map(d->findfirst(f,d), mts)

"""
    transform(f::Function, mts::MTS)

Apply f to each dataframe in mts returning a new MTS object.
"""
function transform(f::Function, mts::MTS)
    dfs = Array{DataFrame}(undef,length(mts))
    for i in 1:length(mts)
        dfs[i] = copy(f(mts[i])) #defensive copy, needed?
    end
    MTS(dfs)
end

"""
    trim(mts::MTS, inds::Vector{Int})

Trim each dataframe in mts according to inds.  For each dataframe, rows 1:inds[i] are kept.  Invalid inds[i] are ignored.  A new MTS object is returned.
"""
function trim(mts::MTS, inds::Vector{Int})
    @assert length(mts) == length(inds)
    dfs = Array{DataFrame}(undef,length(inds))
    for i = 1:length(inds)
        rng_end = inds[i] in 1:nrow(mts[i]) ? inds[i] : nrow(mts[i])
        dfs[i] = convert(DataFrame, mts[i][1:rng_end,:])
    end
    MTS(dfs)
end

"""
    test_mts(rng::AbstractRNG=Random.G LOBAL_RNG)

Generate an MTS populated with some random values for testing use.
"""
function test_mts(rng::AbstractRNG=Random.GLOBAL_RNG)
	R = rand(rng, 20, 3)
    d = DataFrame(R)
    mts = MTS(d, [1, 6, 11, 16])
    mts
end

"""
    transform_cols(f::Function, mts::MTS)

Apply f to each column of all entries of mts
"""
function transform_cols(f::Function, mts::MTS)
    transform(mts) do d
        df = d[:,:]
        for c in names(df)
            df[!,c] = f(df[!,c])
        end
        df
    end
end

"""
    Base.zero(mts::MTS)

Apply zero function to all entries of mts
"""
Base.zero(mts::MTS) = transform_cols(zero, mts)

end # module


text:
# ---
# title: 121. Best Time to Buy and Sell Stock
# id: problem121
# author: Tian Jun
# date: 2020-10-31
# difficulty: Easy
# categories: Array, Dynamic Programming
# link: <https://leetcode.com/problems/best-time-to-buy-and-sell-stock/description/>
# hidden: true
# ---
#
# Say you have an array for which the _i_ th element is the price of a given
# stock on day _i_.
#
# If you were only permitted to complete at most one transaction (i.e., buy one
# and sell one share of the stock), design an algorithm to find the maximum
# profit.
#
# Note that you cannot sell a stock before you buy one.
#
# **Example 1:**
#
#
#
#     Input: [7,1,5,3,6,4]
#     Output: 5
#     Explanation: Buy on day 2 (price = 1) and sell on day 5 (price = 6), profit = 6-1 = 5.
#                  Not 7-1 = 6, as selling price needs to be larger than buying price.
#
#
# **Example 2:**
#
#
#
#     Input: [7,6,4,3,1]
#     Output: 0
#     Explanation: In this case, no transaction is done, i.e. max profit = 0.
#
#
#
## @lc code=start
using LeetCode

## add your code here:
## @lc code=end


text:
using Random
using Plots
#=
Julia Func A:
https://cdn.discordapp.com/attachments/769031254959587330/943626247479636008/Screenshot_20220216-120314_Instagram.jpg

It's a trick question. The equation always equals zero.
This is because the b value is negated twice and natural numbers are never negative or zero.
Even if they could be zero, it'd never be zero because the rational function leaves a limit at x = 0 that equals infinity.
=#

#Eulers
e = exp(1)

#Maximum calculations
tauMax = 10

#Variables
n = 1:tauMax

#SubVars
tauDivs = zeros(Float64, 3)
tauVals = zeros(Float64, tauMax)
imNums = zeros(Float64, tauMax)

function TauCalc(tauMax::Int, tauDivs::Array)
    global tauVals
    global n

    if tauMax > 0
        for i in n
            itr = i

            i^=2
            var = -1/i

            tauDivs[1] = (e*i)^2
            tauDivs[1] /= 24
            tauDivs[2] = (var*i)
            tauDivs[3] = (589*sqrt(complex(-var)))
            tauDivs[3] /= 20
            tauVals[itr] = sum(tauDivs)

        end
    else
    println("Natural Numbers can't be lower than One")
    end
end

function ASum(imNums::Array)
    i = 1

    for var in tauVals
        if(typeof(var) == Complex)
            imNums[i] = var
            i += 1
        end
    end
end

function TauPlot(tauVals::Array, n)
  println("Would you like to see a Plot for n to x values? y/n")

    if (readline() == "y")
        println("Enter Character in Console to Exit")
        gui(plot(1:tauMax,tauVals))

    else
        exit()
    end
    readline()
end

TauCalc(tauMax, tauDivs)
ASum(imNums)
TauPlot(tauVals, n)

exit()


text:
"""
	init_raster_array(matrix::Array{Float64,2}, GSD::Float64, model::LAR, BGcolor::Array{Float64,1})

Orthoprojection of `model` on plane defined by `matrix`, create a raster image with background color `BGcolor`.
"""
function init_raster_array(
    matrix::Array{Float64,2},
    GSD::Float64,
    model::LAR,
    BGcolor::Array{Float64,1},
)

    verts, edges, faces = model
    bbglobalextention = zeros(2)
    ref = zeros(2)

    newcoord = matrix * verts

    for i = 1:2
        extr = extrema(newcoord[i, :])
        bbglobalextention[i] = extr[2] - extr[1]
        ref[i] = extr[i]
    end

    # IMAGE RESOLUTION
    resX = map(Int ∘ trunc, bbglobalextention[1] / GSD) + 1
    resY = map(Int ∘ trunc, bbglobalextention[2] / GSD) + 1

    # Z-BUFFER MATRIX
    rasterquote = fill(-Inf, (resY, resX))

    # RASTER IMAGE MATRIX
    rasterChannels = 3

    RGBtensor = fill(1.0, (rasterChannels, resY, resX))
    RGBtensor[1, :, :] .= BGcolor[1]
    RGBtensor[2, :, :] .= BGcolor[2]
    RGBtensor[3, :, :] .= BGcolor[3]
    # refX=ref[1]
    # refY=ref[2]
    return RGBtensor, rasterquote, ref[1], ref[2]
end

"""
	get_potree_dirs(txtpotreedirs::String)

Return collection of potree directories.
"""
function get_potree_dirs(txtpotreedirs::String)
    if isfile(txtpotreedirs)
        return FileManager.readlines(txtpotreedirs)
    elseif isdir(txtpotreedirs)
        return [txtpotreedirs]
    end
end

"""
	PO2matrix(PO::String, UCS=Matrix{Float64}(Common.I,4,4)::Matrix)

Observation point.
Valid input:
 - "XY+": Top view
 - "XY-": Bottom view
 - "XZ+": Back view
 - "XZ-": Front view
 - "YZ+": Left view
 - "YZ-": Right view
"""
function PO2matrix(PO::String, UCS = Matrix{Float64}(Common.I, 4, 4)::Matrix)
    planecode = PO[1:2]
    @assert planecode == "XY" || planecode == "XZ" || planecode == "YZ" "orthoprojectionimage: $PO not valid view "

    directionview = PO[3]
    @assert directionview == '+' || directionview == '-' "orthoprojectionimage: $PO not valid view "

    coordsystemmatrix = Matrix{Float64}(Common.I, 3, 3)

    # if planecode == XY # top, - bottom
    #     continue
    if planecode == "XZ" # back, - front
        coordsystemmatrix[1, 1] = -1.0
        coordsystemmatrix[2, 2] = 0.0
        coordsystemmatrix[3, 3] = 0.0
        coordsystemmatrix[2, 3] = 1.0
        coordsystemmatrix[3, 2] = 1.0
    elseif planecode == "YZ" # right, - left
        coordsystemmatrix[1, 1] = 0.0
        coordsystemmatrix[2, 2] = 0.0
        coordsystemmatrix[3, 3] = 0.0
        coordsystemmatrix[1, 2] = 1.0
        coordsystemmatrix[2, 3] = 1.0
        coordsystemmatrix[3, 1] = 1.0
    end

    # if directionview == "+"
    #     continue
    if directionview == '-'
        R = [-1.0 0 0; 0 1.0 0; 0 0 -1]
        coordsystemmatrix = R * coordsystemmatrix
    end

    return coordsystemmatrix * UCS[1:3, 1:3]
end


text:
# *********************************************************************************
# REopt, Copyright (c) 2019-2020, Alliance for Sustainable Energy, LLC.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# Redistributions of source code must retain the above copyright notice, this list
# of conditions and the following disclaimer.
#
# Redistributions in binary form must reproduce the above copyright notice, this
# list of conditions and the following disclaimer in the documentation and/or other
# materials provided with the distribution.
#
# Neither the name of the copyright holder nor the names of its contributors may be
# used to endorse or promote products derived from this software without specific
# prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
# OF THE POSSIBILITY OF SUCH DAMAGE.
# *********************************************************************************

"""
    ColdThermalStorageDefaults

    Cold thermal energy storage sytem; specifically, a chilled water system used to
    meet thermal cooling loads.

```julia
Base.@kwdef struct ColdThermalStorageDefaults <: AbstractThermalStorageDefaults
    min_gal::Float64 = 0.0
    max_gal::Float64 = 0.0
    hot_water_temp_degF::Float64 = 56.0
    cool_water_temp_degF::Float64 = 44.0
    internal_efficiency_pct::Float64 = 0.999999
    soc_min_pct::Float64 = 0.1
    soc_init_pct::Float64 = 0.5
    installed_cost_per_gal::Float64 = 1.50
    thermal_decay_rate_fraction::Float64 = 0.0004
    om_cost_per_gal::Float64 = 0.0
    macrs_option_years::Int = 0
    macrs_bonus_pct::Float64 = 0.0
    macrs_itc_reduction::Float64 = 0.0
    total_itc_pct::Float64 = 0.0
    total_rebate_per_kwh::Float64 = 0.0
end
```
"""
Base.@kwdef struct ColdThermalStorageDefaults <: AbstractThermalStorageDefaults
    min_gal::Float64 = 0.0
    max_gal::Float64 = 0.0
    hot_water_temp_degF::Float64 = 56.0
    cool_water_temp_degF::Float64 = 44.0
    internal_efficiency_pct::Float64 = 0.999999
    soc_min_pct::Float64 = 0.1
    soc_init_pct::Float64 = 0.5
    installed_cost_per_gal::Float64 = 1.50
    thermal_decay_rate_fraction::Float64 = 0.0004
    om_cost_per_gal::Float64 = 0.0
    macrs_option_years::Int = 0
    macrs_bonus_pct::Float64 = 0.0
    macrs_itc_reduction::Float64 = 0.0
    total_itc_pct::Float64 = 0.0
    total_rebate_per_kwh::Float64 = 0.0
end

"""
    HotThermalStorageDefaults

```julia
Base.@kwdef struct HotThermalStorageDefaults <: AbstractThermalStorageDefaults
    min_gal::Float64 = 0.0
    max_gal::Float64 = 0.0
    hot_water_temp_degF::Float64 = 180.0
    cool_water_temp_degF::Float64 = 160.0
    internal_efficiency_pct::Float64 = 0.999999
    soc_min_pct::Float64 = 0.1
    soc_init_pct::Float64 = 0.5
    installed_cost_per_gal::Float64 = 1.50
    thermal_decay_rate_fraction::Float64 = 0.0004
    om_cost_per_gal::Float64 = 0.0
    macrs_option_years::Int = 0
    macrs_bonus_pct::Float64 = 0.0
    macrs_itc_reduction::Float64 = 0.0
    total_itc_pct::Float64 = 0.0
    total_rebate_per_kwh::Float64 = 0.0
end
```
"""
Base.@kwdef struct HotThermalStorageDefaults <: AbstractThermalStorageDefaults
    min_gal::Float64 = 0.0
    max_gal::Float64 = 0.0
    hot_water_temp_degF::Float64 = 180.0
    cool_water_temp_degF::Float64 = 160.0
    internal_efficiency_pct::Float64 = 0.999999
    soc_min_pct::Float64 = 0.1
    soc_init_pct::Float64 = 0.5
    installed_cost_per_gal::Float64 = 1.50
    thermal_decay_rate_fraction::Float64 = 0.0004
    om_cost_per_gal::Float64 = 0.0
    macrs_option_years::Int = 0
    macrs_bonus_pct::Float64 = 0.0
    macrs_itc_reduction::Float64 = 0.0
    total_itc_pct::Float64 = 0.0
    total_rebate_per_kwh::Float64 = 0.0
end

"""
    function ThermalStorage(d::Dict, f::Financial, time_steps_per_hour::Int)

Construct ThermalStorage struct from Dict with keys-val pairs from the
REopt [Hot,Cold]ThermalStorage and Financial inputs.
"""
struct ThermalStorage <: AbstractThermalStorage
    min_gal::Float64
    max_gal::Float64
    hot_water_temp_degF::Float64
    cool_water_temp_degF::Float64
    internal_efficiency_pct::Float64
    soc_min_pct::Float64
    soc_init_pct::Float64
    installed_cost_per_gal::Float64
    thermal_decay_rate_fraction::Float64
    om_cost_per_gal::Float64
    macrs_option_years::Int
    macrs_bonus_pct::Float64
    total_rebate_per_kwh::Float64
    min_kw::Float64
    max_kw::Float64
    min_kwh::Float64
    max_kwh::Float64
    installed_cost_per_kwh::Float64
    charge_efficiency::Float64
    discharge_efficiency::Float64
    net_present_cost_per_kwh::Float64
    om_cost_per_kwh::Float64

    function ThermalStorage(s::AbstractThermalStorageDefaults, f::Financial, time_steps_per_hour::Int)

        delta_T_degF = s.hot_water_temp_degF - s.cool_water_temp_degF
        avg_rho_kg_per_m3 = 998.2
        avg_cp_kj_per_kgK = 4.184 #TODO: add CoolProp reference or perform analogous calculations for water and build lookup tables
        kwh_per_gal = convert_gal_to_kwh(delta_T_degF, avg_rho_kg_per_m3, avg_cp_kj_per_kgK)
        min_kwh = s.min_gal * kwh_per_gal
        max_kwh = s.max_gal * kwh_per_gal
        min_kw = min_kwh * time_steps_per_hour
        max_kw = max_kwh * time_steps_per_hour
        om_cost_per_kwh = s.om_cost_per_gal / kwh_per_gal

        charge_efficiency = s.internal_efficiency_pct^0.5
        discharge_efficiency = s.internal_efficiency_pct^0.5
        installed_cost_per_kwh = s.installed_cost_per_gal / kwh_per_gal

        net_present_cost_per_kwh = effective_cost(;
            itc_basis = installed_cost_per_kwh,
            replacement_cost = 0.0,
            replacement_year = 100,
            discount_rate = f.owner_discount_pct,
            tax_rate = f.owner_tax_pct,
            itc = s.total_itc_pct,
            macrs_schedule = s.macrs_option_years == 7 ? f.macrs_seven_year : f.macrs_five_year,
            macrs_bonus_pct = s.macrs_bonus_pct,
            macrs_itc_reduction = s.macrs_itc_reduction
        ) - s.total_rebate_per_kwh

        return new(
            s.min_gal,
            s.max_gal,
            s.hot_water_temp_degF,
            s.cool_water_temp_degF,
            s.internal_efficiency_pct,
            s.soc_min_pct,
            s.soc_init_pct,
            s.installed_cost_per_gal,
            s.thermal_decay_rate_fraction,
            s.om_cost_per_gal,
            s.macrs_option_years,
            s.macrs_bonus_pct,
            s.total_rebate_per_kwh,
            min_kw,
            max_kw,
            min_kwh,
            max_kwh,
            installed_cost_per_kwh,
            charge_efficiency,
            discharge_efficiency,
            net_present_cost_per_kwh,
            om_cost_per_kwh,
        )
    end
end

max_stars_repo_name: NREL/REopt

max_issues_repo_name: NREL/REopt

max_forks_repo_name: NREL/REopt


text:
using Plots
n,m,N = 6,3,21
times = range(0,pi,length=N)
X = [SA[sin(t), cos(t), t, t^2, sin(t) + t, sqrt(t)] for t in times]
U = [@SVector rand(m) for k = 1:N-1]
Z = RD.Traj(X, U, push!(diff(times),0))

plot(X)
plot(X, inds=1:2)
plot(times, X, inds=1:2)
plot!(times, X, inds=3:n)
plot(times, X)  # should be the same the previous
p = plot(times, X, color=[:black :red :green :blue :yellow :purple])
@test length(p.series_list) == n
@test p.series_list[1].plotattributes[:linecolor] == RGBA(0,0,0)

# Traj
p = traj2(X)
traj2!(-sin.(times), cos.(times))
@test length(p.series_list) == 2

p = traj2(Z, xind=3, yind=5, linewidth=2, label="something")
@test length(p.series_list) == 1

p = plot(Z)
@test length(p.series_list) == 9

p = plot(Z, inds=3:6)
@test length(p.series_list) == 4


text:
@testset "Promotion" begin
    Mod.@polyvar x y
    @inferred x*y+x
    @test [x, x*y+x, x] isa Vector{<:AbstractPolynomial{Int}}
    @test eltype([1, x/y, x]) <: RationalPoly{<:AbstractTerm{Int}, <:AbstractTerm{Int}}
    @test [(x^2-2x+2) x; x x^2] isa Matrix{<:AbstractPolynomial{Int}}
    @test [2.0x, 3x] isa Vector{<:AbstractTerm{Float64}}
    @inferred Any[x*y, x+y]
    @test Any[x*y, x+y] isa Vector{Any}
    @test [x*y, x+y] isa Vector{<:AbstractPolynomial{Int}}
    @test [2x*y, x+y] isa Vector{<:AbstractPolynomial{Int}}
    @test eltype([2.0x, x/y]) <: RationalPoly{<:AbstractTerm{Float64}, <:AbstractTerm{Int}}
    @test eltype([2.0x, x/y, 1y]) <: RationalPoly{<:AbstractTerm{Float64}, <:AbstractTerm{Int}}
    @test eltype([2x+y, x/2.0y, x+1y]) <: RationalPoly{<:AbstractPolynomial{Int}, <:AbstractTerm{Float64}}
    @test eltype([-1/x^2, 1]) <: RationalPoly{<:AbstractTerm{Int}, <:AbstractTerm{Int}}

    X = [x, y]
    Y = [1 2; 3 4] * X
    @test Y[1] == x + 2y
    @test Y[2] == 3x + 4y
    Y = X' * [1 2; 3 4]
    @test Y[1] == x + 3y
    @test Y[2] == 2x + 4y
    @test dot(X, [1 2; 3 4] * X) == x^2 + 5x*y + 4y^2
end


text:
#=
an example on how to calculate the clebsch gordon coefficients for some su3 irreps
=#
using SUNRepresentations;

a = SUNIrrep(2,1,0);
b = SUNIrrep(2,1,0);
c = SUNIrrep(2,1,0);

CGC(a,b,c)


text:
struct HS071 <: MOI.AbstractNLPEvaluator
    enable_hessian::Bool
end

# hs071
# min x1 * x4 * (x1 + x2 + x3) + x3
# st  x1 * x2 * x3 * x4 >= 25
#     x1^2 + x2^2 + x3^2 + x4^2 = 40
#     1 <= x1, x2, x3, x4 <= 5
# Start at (1,5,5,1)
# End at (1.000..., 4.743..., 3.821..., 1.379...)

function MOI.initialize(d::HS071, requested_features::Vector{Symbol})
    for feat in requested_features
        if !(feat in MOI.features_available(d))
            error("Unsupported feature $feat")
            # TODO: implement Jac-vec and Hess-vec products
            # for solvers that need them
        end
    end
end

function MOI.features_available(d::HS071)
    if d.enable_hessian
        return [:Grad, :Jac, :Hess]
    else
        return [:Grad, :Jac]
    end
end

MOI.eval_objective(d::HS071, x) = x[1] * x[4] * (x[1] + x[2] + x[3]) + x[3]

function MOI.eval_constraint(d::HS071, g, x)
    g[1] = x[1]   * x[2]   * x[3]   * x[4]
    g[2] = x[1]^2 + x[2]^2 + x[3]^2 + x[4]^2
end

function MOI.eval_objective_gradient(d::HS071, grad_f, x)
    grad_f[1] = x[1] * x[4] + x[4] * (x[1] + x[2] + x[3])
    grad_f[2] = x[1] * x[4]
    grad_f[3] = x[1] * x[4] + 1
    grad_f[4] = x[1] * (x[1] + x[2] + x[3])
end

function MOI.jacobian_structure(d::HS071)
    return Tuple{Int64,Int64}[(1,1), (1,2), (1,3), (1,4), (2,1), (2,2),
                              (2,3), (2,4)]
end
# lower triangle only
function MOI.hessian_lagrangian_structure(d::HS071)
    @assert d.enable_hessian
    return Tuple{Int64,Int64}[(1,1), (2,1), (2,2), (3,1), (3,2), (3,3),
                              (4,1), (4,2), (4,3), (4,4)]
end

function MOI.eval_constraint_jacobian(d::HS071, J, x)
    # Constraint (row) 1
    J[1] = x[2]*x[3]*x[4]  # 1,1
    J[2] = x[1]*x[3]*x[4]  # 1,2
    J[3] = x[1]*x[2]*x[4]  # 1,3
    J[4] = x[1]*x[2]*x[3]  # 1,4
    # Constraint (row) 2
    J[5] = 2*x[1]  # 2,1
    J[6] = 2*x[2]  # 2,2
    J[7] = 2*x[3]  # 2,3
    J[8] = 2*x[4]  # 2,4
end

function MOI.eval_hessian_lagrangian(d::HS071, H, x, σ, μ)
    @assert d.enable_hessian
    # Again, only lower left triangle
    # Objective
    H[1] = σ * (2*x[4])               # 1,1
    H[2] = σ * (  x[4])               # 2,1
    H[3] = 0                          # 2,2
    H[4] = σ * (  x[4])               # 3,1
    H[5] = 0                          # 3,2
    H[6] = 0                          # 3,3
    H[7] = σ* (2*x[1] + x[2] + x[3])  # 4,1
    H[8] = σ * (  x[1])               # 4,2
    H[9] = σ * (  x[1])               # 4,3
    H[10] = 0                         # 4,4

    # First constraint
    H[2] += μ[1] * (x[3] * x[4])  # 2,1
    H[4] += μ[1] * (x[2] * x[4])  # 3,1
    H[5] += μ[1] * (x[1] * x[4])  # 3,2
    H[7] += μ[1] * (x[2] * x[3])  # 4,1
    H[8] += μ[1] * (x[1] * x[3])  # 4,2
    H[9] += μ[1] * (x[1] * x[2])  # 4,3

    # Second constraint
    H[1]  += μ[2] * 2  # 1,1
    H[3]  += μ[2] * 2  # 2,2
    H[6]  += μ[2] * 2  # 3,3
    H[10] += μ[2] * 2  # 4,4

end

function hs071test_template(model::MOI.ModelLike, config::TestConfig, evaluator::HS071)
    atol = config.atol
    rtol = config.rtol

    @test MOI.supports(model, MOI.NLPBlock())
    @test MOI.supports_constraint(model, MOI.SingleVariable, MOI.LessThan{Float64})
    @test MOI.supports_constraint(model, MOI.SingleVariable, MOI.GreaterThan{Float64})
    @test MOI.supports(model, MOI.VariablePrimalStart(), MOI.VariableIndex)

    MOI.empty!(model)
    @test MOI.is_empty(model)

    lb = [25.0, 40.0]
    ub = [Inf, 40.0]

    block_data = MOI.NLPBlockData(MOI.NLPBoundsPair.(lb, ub), evaluator, true)

    v = MOI.add_variables(model, 4)
    @test MOI.get(model, MOI.NumberOfVariables()) == 4

    l = [1.0,1.0,1.0,1.0]
    u = [5.0,5.0,5.0,5.0]
    start = [1,5,5,1]

    for i in 1:4
        MOI.add_constraint(model, MOI.SingleVariable(v[i]), MOI.LessThan(u[i]))
        MOI.add_constraint(model, MOI.SingleVariable(v[i]), MOI.GreaterThan(l[i]))
        MOI.set(model, MOI.VariablePrimalStart(), v[i], start[i])
    end

    MOI.set(model, MOI.NLPBlock(), block_data)
    MOI.set(model, MOI.ObjectiveSense(), MOI.MIN_SENSE)

    # TODO: config.query tests
    if config.solve
        MOI.optimize!(model)

        @test MOI.get(model, MOI.TerminationStatus()) == config.optimal_status

        @test MOI.get(model, MOI.ResultCount()) >= 1

        @test MOI.get(model, MOI.PrimalStatus()) == MOI.FEASIBLE_POINT

        @test MOI.get(model, MOI.ObjectiveValue()) ≈ 17.014017145179164 atol=atol rtol=rtol

        optimal_v = [1.0, 4.7429996418092970, 3.8211499817883077, 1.3794082897556983]

        @test MOI.get(model, MOI.VariablePrimal(), v) ≈ optimal_v atol=atol rtol=rtol

        # TODO: Duals? Maybe better to test on a convex instance.
    end
end

hs071_test(model, config) = hs071test_template(model, config, HS071(true))
hs071_no_hessian_test(model, config) = hs071test_template(model, config, HS071(false))

# Test for FEASIBILITY_SENSE.
# Find x satisfying x^2 == 1.
struct FeasibilitySenseEvaluator <: MOI.AbstractNLPEvaluator
    enable_hessian::Bool
end

function MOI.initialize(d::FeasibilitySenseEvaluator,
                         requested_features::Vector{Symbol})
    for feat in requested_features
        if !(feat in MOI.features_available(d))
            error("Unsupported feature $feat")
            # TODO: implement Jac-vec and Hess-vec products
            # for solvers that need them
        end
    end
end

function MOI.features_available(d::FeasibilitySenseEvaluator)
    if d.enable_hessian
        return [:Grad, :Jac, :Hess]
    else
        return [:Grad, :Jac]
    end
end

MOI.eval_objective(d::FeasibilitySenseEvaluator, x) = 0.0

function MOI.eval_constraint(d::FeasibilitySenseEvaluator, g, x)
    g[1] = x[1]^2
end

function MOI.eval_objective_gradient(d::FeasibilitySenseEvaluator, grad_f, x)
    grad_f[1] = 0.0
end

function MOI.jacobian_structure(d::FeasibilitySenseEvaluator)
    return Tuple{Int64,Int64}[(1,1)]
end

function MOI.hessian_lagrangian_structure(d::FeasibilitySenseEvaluator)
    @assert d.enable_hessian
    return Tuple{Int64,Int64}[(1,1)]
end

function MOI.eval_constraint_jacobian(d::FeasibilitySenseEvaluator, J, x)
    J[1] = 2x[1]
end

function MOI.eval_hessian_lagrangian(d::FeasibilitySenseEvaluator, H, x, σ, μ)
    @assert d.enable_hessian
    H[1] = 2μ[1] # 1,1
end

function feasibility_sense_test_template(model::MOI.ModelLike,
                                         config::TestConfig,
                                         set_has_objective::Bool,
                                         evaluator::FeasibilitySenseEvaluator)
    atol = config.atol
    rtol = config.rtol

    @test MOI.supports(model, MOI.NLPBlock())
    @test MOI.supports(model, MOI.VariablePrimalStart(), MOI.VariableIndex)

    MOI.empty!(model)
    @test MOI.is_empty(model)

    lb = [1.0]
    ub = [1.0]

    block_data = MOI.NLPBlockData(MOI.NLPBoundsPair.(lb, ub), evaluator,
                                  set_has_objective)

    x = MOI.add_variable(model)
    @test MOI.get(model, MOI.NumberOfVariables()) == 1

    # Avoid starting at zero because it's a critial point.
    MOI.set(model, MOI.VariablePrimalStart(), x, 1.5)

    MOI.set(model, MOI.NLPBlock(), block_data)
    MOI.set(model, MOI.ObjectiveSense(), MOI.FEASIBILITY_SENSE)

    # TODO: config.query tests
    if config.solve
        MOI.optimize!(model)

        @test MOI.get(model, MOI.TerminationStatus()) == config.optimal_status

        @test MOI.get(model, MOI.ResultCount()) >= 1

        @test MOI.get(model, MOI.PrimalStatus()) == MOI.FEASIBLE_POINT

        @test MOI.get(model, MOI.ObjectiveValue()) ≈ 0.0 atol=atol rtol=rtol

        @test MOI.get(model, MOI.VariablePrimal(), x) ≈ 1.0 atol=atol rtol=rtol
    end
end

function feasibility_sense_with_objective_and_hessian_test(model, config)
    feasibility_sense_test_template(model, config, true,
                                    FeasibilitySenseEvaluator(true))
end

function feasibility_sense_with_objective_and_no_hessian_test(model, config)
    feasibility_sense_test_template(model, config, true,
                                    FeasibilitySenseEvaluator(false))
end

function feasibility_sense_with_no_objective_and_with_hessian_test(model, config)
    feasibility_sense_test_template(model, config, false,
                                    FeasibilitySenseEvaluator(true))
end

function feasibility_sense_with_no_objective_and_no_hessian_test(model, config)
    feasibility_sense_test_template(model, config, false,
                                    FeasibilitySenseEvaluator(false))
end

function nlp_objective_and_moi_objective_test(model::MOI.ModelLike,
                                              config::TestConfig)
    atol = config.atol
    rtol = config.rtol

    @test MOI.supports(model, MOI.NLPBlock())
    @test MOI.supports(model, MOI.VariablePrimalStart(), MOI.VariableIndex)

    MOI.empty!(model)
    @test MOI.is_empty(model)

    lb = [1.0]
    ub = [2.0]

    block_data = MOI.NLPBlockData(MOI.NLPBoundsPair.(lb, ub),
                                  FeasibilitySenseEvaluator(true), true)

    x = MOI.add_variable(model)
    @test MOI.get(model, MOI.NumberOfVariables()) == 1

    # Avoid starting at zero because it's a critial point.
    MOI.set(model, MOI.VariablePrimalStart(), x, 1.5)

    MOI.set(model, MOI.NLPBlock(), block_data)
    MOI.set(model, MOI.ObjectiveSense(), MOI.MAX_SENSE)
    f_x =  MOI.ScalarAffineFunction([MOI.ScalarAffineTerm(1.0, x)], 0.0)
    # This objective function should be ignored.
    MOI.set(model, MOI.ObjectiveFunction{typeof(f_x)}(), f_x)

    # TODO: config.query tests
    if config.solve
        MOI.optimize!(model)

        @test MOI.get(model, MOI.TerminationStatus()) == config.optimal_status

        @test MOI.get(model, MOI.ResultCount()) >= 1

        @test MOI.get(model, MOI.PrimalStatus()) == MOI.FEASIBLE_POINT

        @test MOI.get(model, MOI.ObjectiveValue()) ≈ 0.0 atol=atol rtol=rtol

        @test 1.0 ≤ MOI.get(model, MOI.VariablePrimal(), x) ≤ 2.0
    end
end

const nlptests = Dict("hs071" => hs071_test,
                      "hs071_no_hessian" => hs071_no_hessian_test,
                      "feasibility_sense_with_objective_and_hessian" =>
                      feasibility_sense_with_objective_and_hessian_test,
                      "feasibility_sense_with_objective_and_no_hessian" =>
                      feasibility_sense_with_objective_and_no_hessian_test,
                      "feasibility_sense_with_no_objective_and_with_hessian" =>
                      feasibility_sense_with_no_objective_and_with_hessian_test,
                      "feasibility_sense_with_no_objective_and_no_hessian" =>
                      feasibility_sense_with_no_objective_and_no_hessian_test,
                      "nlp_objective_and_moi_objective" =>
                      nlp_objective_and_moi_objective_test
                      )

@moitestset nlp


text:
abstract type Component end

abstract type TransistorModel <: Component end

#= struct QuadraticModel <: TransistorModel
    parameters::Dict{Symbol,Any}
    material::SemiconductorMaterial
end =#

# Id(Vg,Vd,Vs,Vb,m::TransistorModel) = 0.0

# Id(Vg,Vd,Vs,m::TransistorModel) = Id(Vg,Vd,Vs,Vs,m)

# gm(Vg,Vd,Vs,Vb,m::TransistorModel) = gradient(x-> Id(x, Vd, Vs, Vb,m),Vg)[1]
# #Symbolics.@register gm(Vg,Vd,Vs,Vb,m::TransistorModel)

# gm(Vg,Vd,Vs,m::TransistorModel) = gradient(x-> Id(x, Vd, Vs,m),Vg)[1]

# gmId(Vg,Vd,Vs,Vb,m::TransistorModel) = gradient(x-> log(Id(x, Vd, Vs, Vb,m)),Vg)[1]

# gmId(Vg,Vd,Vs,m::TransistorModel) = gradient(x-> log(Id(x, Vd, Vs,m)),Vg)[1]

# gds(Vg,Vd,Vs,Vb,m::TransistorModel) = gradient(x-> Id(Vg, x, Vs, Vb,m),Vd)[1]
# #Symbolics.@register gds(Vg,Vd,Vs,Vb,m::TransistorModel)

# gds(Vg,Vd,Vs,m::TransistorModel) = gradient(x-> Id(Vg, x, Vs,m),Vd)[1]

# gdsId(Vg,Vd,Vs,Vb,m::TransistorModel) = gradient(x-> log(Id(Vg, x, Vs, Vb,m)),Vd)[1]

# gdsId(Vg,Vd,Vs,m::TransistorModel) = gradient(x-> log(Id(Vg, x, Vs,m)),Vd)[1]


text:
import CLBLAS
import OpenCL

    const clblas = CLBLAS
    clblas.setup()

    const cl = OpenCL

    device, ctx, queue = clblas.get_next_compute_context()

    N = unsigned(5)
    data = Array(Float32, 5)
    data[1] = 1.1
    data[2] = 2.22
    data[3] = 3.333
    data[4] = 4.4444
    data[5] = 5.55555

    bufX = cl.Buffer(Float32, ctx, (:r, :copy),hostbuf=data)

    bufNRM2 = cl.Buffer(Float32, ctx, :w, 1)
    scratchBuff = cl.Buffer(Float32, ctx, :rw, 2 * length(data))

    offNRM2 = offx = unsigned(0)
    incx = cl.cl_int(1)
    ncq = cl.cl_uint(1)
    clq = queue.id
    newl = cl.cl_uint(0)

    event = cl.UserEvent(ctx, retain=true)
    ptrEvent = [event.id]

    clblas.clblasSnrm2( N, bufNRM2.id, offNRM2, bufX.id, offx, incx, scratchBuff.id, ncq, [clq], newl, C_NULL, ptrEvent);

    cl.api.clWaitForEvents(cl.cl_uint(1), ptrEvent)

    result = Array(Float32, 1)
    cl.enqueue_read_buffer(queue, bufNRM2, result, unsigned(0), nothing, true)

    expected = BLAS.nrm2(5, data, 1)
    println(result)
    println("------------")
    println(expected)

    try
        @assert(isapprox(norm(expected - result[1]), zero(Float32)))
        info("success!")
    finally
        clblas.teardown()
    end


text:
""" :( """
SP_u(::Type{FT}) where {FT} = z -> FT(1)

""" :( """
SP_v(::Type{FT}) where {FT} = z -> FT(0)

""" :( """
SP_θ_liq_ice(::Type{FT}) where {FT} =
    z -> if z <= 974.0
        FT(300)
    elseif z < 1074.0
        FT(300) + (z - 974) * FT(0.08)
    else
        FT(308) + (z - 1074) * FT(0.003)
    end

""" :( """
SP_q_tot(::Type{FT}) where {FT} = z -> FT(0)

""" :( """
SP_geostrophic_u(::Type{FT}) where {FT} = z -> FT(1)

""" :( """
SP_geostrophic_v(::Type{FT}) where {FT} = z -> FT(0)