HydPy 6.2.dev1__cp313-cp313-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- hydpy/__init__.py +275 -0
- hydpy/aliases.py +2554 -0
- hydpy/auxs/__init__.py +0 -0
- hydpy/auxs/anntools.py +1305 -0
- hydpy/auxs/armatools.py +883 -0
- hydpy/auxs/calibtools.py +3337 -0
- hydpy/auxs/interptools.py +1094 -0
- hydpy/auxs/iuhtools.py +543 -0
- hydpy/auxs/networktools.py +597 -0
- hydpy/auxs/ppolytools.py +809 -0
- hydpy/auxs/quadtools.py +61 -0
- hydpy/auxs/roottools.py +228 -0
- hydpy/auxs/smoothtools.py +273 -0
- hydpy/auxs/statstools.py +2125 -0
- hydpy/auxs/validtools.py +81 -0
- hydpy/conf/HydPyConfigBase.xsd +68637 -0
- hydpy/conf/HydPyConfigBase.xsdt +358 -0
- hydpy/conf/HydPyConfigMultipleRuns.xsd +25 -0
- hydpy/conf/HydPyConfigSingleRun.xsd +24 -0
- hydpy/conf/__init__.py +0 -0
- hydpy/conf/a_coefficients_explicit_lobatto_sequence.npy +0 -0
- hydpy/conf/support_points_for_smoothpar_logistic2.npy +0 -0
- hydpy/config.py +42 -0
- hydpy/core/__init__.py +0 -0
- hydpy/core/aliastools.py +214 -0
- hydpy/core/autodoctools.py +1947 -0
- hydpy/core/auxfiletools.py +1169 -0
- hydpy/core/devicetools.py +3810 -0
- hydpy/core/exceptiontools.py +269 -0
- hydpy/core/filetools.py +1985 -0
- hydpy/core/hydpytools.py +3089 -0
- hydpy/core/importtools.py +1398 -0
- hydpy/core/indextools.py +345 -0
- hydpy/core/itemtools.py +1849 -0
- hydpy/core/masktools.py +460 -0
- hydpy/core/modeltools.py +4868 -0
- hydpy/core/netcdftools.py +2683 -0
- hydpy/core/objecttools.py +2023 -0
- hydpy/core/optiontools.py +1045 -0
- hydpy/core/parametertools.py +4674 -0
- hydpy/core/printtools.py +222 -0
- hydpy/core/propertytools.py +643 -0
- hydpy/core/pubtools.py +254 -0
- hydpy/core/selectiontools.py +1571 -0
- hydpy/core/sequencetools.py +4476 -0
- hydpy/core/seriestools.py +339 -0
- hydpy/core/testtools.py +2483 -0
- hydpy/core/timetools.py +3567 -0
- hydpy/core/typingtools.py +333 -0
- hydpy/core/variabletools.py +2615 -0
- hydpy/cythons/__init__.py +24 -0
- hydpy/cythons/annutils.pxd +33 -0
- hydpy/cythons/annutils.pyi +25 -0
- hydpy/cythons/annutils.pyx +120 -0
- hydpy/cythons/autogen/__init__.py +0 -0
- hydpy/cythons/autogen/annutils.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/annutils.pxd +42 -0
- hydpy/cythons/autogen/annutils.pyx +129 -0
- hydpy/cythons/autogen/c_arma.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_arma.pxd +179 -0
- hydpy/cythons/autogen/c_arma.pyx +356 -0
- hydpy/cythons/autogen/c_arma_rimorido.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_arma_rimorido.pxd +179 -0
- hydpy/cythons/autogen/c_arma_rimorido.pyx +356 -0
- hydpy/cythons/autogen/c_conv.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_conv.pxd +198 -0
- hydpy/cythons/autogen/c_conv.pyx +491 -0
- hydpy/cythons/autogen/c_conv_idw.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_conv_idw.pxd +124 -0
- hydpy/cythons/autogen/c_conv_idw.pyx +264 -0
- hydpy/cythons/autogen/c_conv_idw_ed.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_conv_idw_ed.pxd +197 -0
- hydpy/cythons/autogen/c_conv_idw_ed.pyx +481 -0
- hydpy/cythons/autogen/c_conv_nn.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_conv_nn.pxd +120 -0
- hydpy/cythons/autogen/c_conv_nn.pyx +224 -0
- hydpy/cythons/autogen/c_dam.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dam.pxd +805 -0
- hydpy/cythons/autogen/c_dam.pyx +1477 -0
- hydpy/cythons/autogen/c_dam_llake.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dam_llake.pxd +364 -0
- hydpy/cythons/autogen/c_dam_llake.pyx +705 -0
- hydpy/cythons/autogen/c_dam_lreservoir.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dam_lreservoir.pxd +365 -0
- hydpy/cythons/autogen/c_dam_lreservoir.pyx +708 -0
- hydpy/cythons/autogen/c_dam_lretention.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dam_lretention.pxd +340 -0
- hydpy/cythons/autogen/c_dam_lretention.pyx +625 -0
- hydpy/cythons/autogen/c_dam_pump.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dam_pump.pxd +402 -0
- hydpy/cythons/autogen/c_dam_pump.pyx +724 -0
- hydpy/cythons/autogen/c_dam_pump_sluice.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dam_pump_sluice.pxd +452 -0
- hydpy/cythons/autogen/c_dam_pump_sluice.pyx +829 -0
- hydpy/cythons/autogen/c_dam_sluice.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dam_sluice.pxd +404 -0
- hydpy/cythons/autogen/c_dam_sluice.pyx +726 -0
- hydpy/cythons/autogen/c_dam_v001.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dam_v001.pxd +452 -0
- hydpy/cythons/autogen/c_dam_v001.pyx +816 -0
- hydpy/cythons/autogen/c_dam_v002.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dam_v002.pxd +394 -0
- hydpy/cythons/autogen/c_dam_v002.pyx +703 -0
- hydpy/cythons/autogen/c_dam_v003.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dam_v003.pxd +417 -0
- hydpy/cythons/autogen/c_dam_v003.pyx +744 -0
- hydpy/cythons/autogen/c_dam_v004.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dam_v004.pxd +486 -0
- hydpy/cythons/autogen/c_dam_v004.pyx +891 -0
- hydpy/cythons/autogen/c_dam_v005.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dam_v005.pxd +524 -0
- hydpy/cythons/autogen/c_dam_v005.pyx +928 -0
- hydpy/cythons/autogen/c_dummy.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dummy.pxd +151 -0
- hydpy/cythons/autogen/c_dummy.pyx +263 -0
- hydpy/cythons/autogen/c_dummy_interceptedwater.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dummy_interceptedwater.pxd +69 -0
- hydpy/cythons/autogen/c_dummy_interceptedwater.pyx +104 -0
- hydpy/cythons/autogen/c_dummy_node2node.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dummy_node2node.pxd +89 -0
- hydpy/cythons/autogen/c_dummy_node2node.pyx +148 -0
- hydpy/cythons/autogen/c_dummy_snowalbedo.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dummy_snowalbedo.pxd +69 -0
- hydpy/cythons/autogen/c_dummy_snowalbedo.pyx +104 -0
- hydpy/cythons/autogen/c_dummy_snowcover.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dummy_snowcover.pxd +69 -0
- hydpy/cythons/autogen/c_dummy_snowcover.pyx +104 -0
- hydpy/cythons/autogen/c_dummy_snowycanopy.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dummy_snowycanopy.pxd +69 -0
- hydpy/cythons/autogen/c_dummy_snowycanopy.pyx +104 -0
- hydpy/cythons/autogen/c_dummy_soilwater.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dummy_soilwater.pxd +69 -0
- hydpy/cythons/autogen/c_dummy_soilwater.pyx +104 -0
- hydpy/cythons/autogen/c_evap.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_evap.pxd +1029 -0
- hydpy/cythons/autogen/c_evap.pyx +2601 -0
- hydpy/cythons/autogen/c_evap_aet_hbv96.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_evap_aet_hbv96.pxd +227 -0
- hydpy/cythons/autogen/c_evap_aet_hbv96.pyx +584 -0
- hydpy/cythons/autogen/c_evap_aet_minhas.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_evap_aet_minhas.pxd +193 -0
- hydpy/cythons/autogen/c_evap_aet_minhas.pyx +478 -0
- hydpy/cythons/autogen/c_evap_aet_morsim.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_evap_aet_morsim.pxd +681 -0
- hydpy/cythons/autogen/c_evap_aet_morsim.pyx +1642 -0
- hydpy/cythons/autogen/c_evap_pet_ambav1.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_evap_pet_ambav1.pxd +532 -0
- hydpy/cythons/autogen/c_evap_pet_ambav1.pyx +1296 -0
- hydpy/cythons/autogen/c_evap_pet_hbv96.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_evap_pet_hbv96.pxd +179 -0
- hydpy/cythons/autogen/c_evap_pet_hbv96.pyx +328 -0
- hydpy/cythons/autogen/c_evap_pet_m.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_evap_pet_m.pxd +124 -0
- hydpy/cythons/autogen/c_evap_pet_m.pyx +214 -0
- hydpy/cythons/autogen/c_evap_pet_mlc.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_evap_pet_mlc.pxd +126 -0
- hydpy/cythons/autogen/c_evap_pet_mlc.pyx +214 -0
- hydpy/cythons/autogen/c_evap_ret_fao56.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_evap_ret_fao56.pxd +305 -0
- hydpy/cythons/autogen/c_evap_ret_fao56.pyx +624 -0
- hydpy/cythons/autogen/c_evap_ret_io.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_evap_ret_io.pxd +112 -0
- hydpy/cythons/autogen/c_evap_ret_io.pyx +176 -0
- hydpy/cythons/autogen/c_evap_ret_tw2002.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_evap_ret_tw2002.pxd +139 -0
- hydpy/cythons/autogen/c_evap_ret_tw2002.pyx +273 -0
- hydpy/cythons/autogen/c_exch.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_exch.pxd +230 -0
- hydpy/cythons/autogen/c_exch.pyx +462 -0
- hydpy/cythons/autogen/c_exch_branch_hbv96.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_exch_branch_hbv96.pxd +134 -0
- hydpy/cythons/autogen/c_exch_branch_hbv96.pyx +255 -0
- hydpy/cythons/autogen/c_exch_waterlevel.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_exch_waterlevel.pxd +54 -0
- hydpy/cythons/autogen/c_exch_waterlevel.pyx +78 -0
- hydpy/cythons/autogen/c_exch_weir_hbv96.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_exch_weir_hbv96.pxd +156 -0
- hydpy/cythons/autogen/c_exch_weir_hbv96.pyx +282 -0
- hydpy/cythons/autogen/c_ga.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_ga.pxd +353 -0
- hydpy/cythons/autogen/c_ga.pyx +1204 -0
- hydpy/cythons/autogen/c_ga_garto.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_ga_garto.pxd +330 -0
- hydpy/cythons/autogen/c_ga_garto.pyx +1105 -0
- hydpy/cythons/autogen/c_ga_garto_submodel1.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_ga_garto_submodel1.pxd +236 -0
- hydpy/cythons/autogen/c_ga_garto_submodel1.pyx +944 -0
- hydpy/cythons/autogen/c_gland.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_gland.pxd +437 -0
- hydpy/cythons/autogen/c_gland.pyx +726 -0
- hydpy/cythons/autogen/c_gland_gr4.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_gland_gr4.pxd +382 -0
- hydpy/cythons/autogen/c_gland_gr4.pyx +605 -0
- hydpy/cythons/autogen/c_gland_gr5.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_gland_gr5.pxd +368 -0
- hydpy/cythons/autogen/c_gland_gr5.pyx +568 -0
- hydpy/cythons/autogen/c_gland_gr6.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_gland_gr6.pxd +420 -0
- hydpy/cythons/autogen/c_gland_gr6.pyx +673 -0
- hydpy/cythons/autogen/c_hland.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_hland.pxd +855 -0
- hydpy/cythons/autogen/c_hland.pyx +2486 -0
- hydpy/cythons/autogen/c_hland_96.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_hland_96.pxd +631 -0
- hydpy/cythons/autogen/c_hland_96.pyx +1724 -0
- hydpy/cythons/autogen/c_hland_96c.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_hland_96c.pxd +621 -0
- hydpy/cythons/autogen/c_hland_96c.pyx +1822 -0
- hydpy/cythons/autogen/c_hland_96p.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_hland_96p.pxd +683 -0
- hydpy/cythons/autogen/c_hland_96p.pyx +1911 -0
- hydpy/cythons/autogen/c_kinw.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_kinw.pxd +509 -0
- hydpy/cythons/autogen/c_kinw.pyx +965 -0
- hydpy/cythons/autogen/c_kinw_williams.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_kinw_williams.pxd +409 -0
- hydpy/cythons/autogen/c_kinw_williams.pyx +763 -0
- hydpy/cythons/autogen/c_kinw_williams_ext.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_kinw_williams_ext.pxd +220 -0
- hydpy/cythons/autogen/c_kinw_williams_ext.pyx +440 -0
- hydpy/cythons/autogen/c_lland.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_lland.pxd +1386 -0
- hydpy/cythons/autogen/c_lland.pyx +3679 -0
- hydpy/cythons/autogen/c_lland_dd.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_lland_dd.pxd +679 -0
- hydpy/cythons/autogen/c_lland_dd.pyx +1719 -0
- hydpy/cythons/autogen/c_lland_knauf.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_lland_knauf.pxd +1096 -0
- hydpy/cythons/autogen/c_lland_knauf.pyx +2784 -0
- hydpy/cythons/autogen/c_lland_knauf_ic.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_lland_knauf_ic.pxd +1369 -0
- hydpy/cythons/autogen/c_lland_knauf_ic.pyx +3625 -0
- hydpy/cythons/autogen/c_meteo.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_meteo.pxd +469 -0
- hydpy/cythons/autogen/c_meteo.pyx +879 -0
- hydpy/cythons/autogen/c_meteo_clear_glob_io.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_meteo_clear_glob_io.pxd +75 -0
- hydpy/cythons/autogen/c_meteo_clear_glob_io.pyx +107 -0
- hydpy/cythons/autogen/c_meteo_glob_fao56.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_meteo_glob_fao56.pxd +209 -0
- hydpy/cythons/autogen/c_meteo_glob_fao56.pyx +339 -0
- hydpy/cythons/autogen/c_meteo_glob_io.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_meteo_glob_io.pxd +63 -0
- hydpy/cythons/autogen/c_meteo_glob_io.pyx +91 -0
- hydpy/cythons/autogen/c_meteo_glob_morsim.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_meteo_glob_morsim.pxd +289 -0
- hydpy/cythons/autogen/c_meteo_glob_morsim.pyx +527 -0
- hydpy/cythons/autogen/c_meteo_precip_io.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_meteo_precip_io.pxd +112 -0
- hydpy/cythons/autogen/c_meteo_precip_io.pyx +176 -0
- hydpy/cythons/autogen/c_meteo_psun_sun_glob_io.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_meteo_psun_sun_glob_io.pxd +87 -0
- hydpy/cythons/autogen/c_meteo_psun_sun_glob_io.pyx +123 -0
- hydpy/cythons/autogen/c_meteo_sun_fao56.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_meteo_sun_fao56.pxd +209 -0
- hydpy/cythons/autogen/c_meteo_sun_fao56.pyx +343 -0
- hydpy/cythons/autogen/c_meteo_sun_morsim.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_meteo_sun_morsim.pxd +286 -0
- hydpy/cythons/autogen/c_meteo_sun_morsim.pyx +519 -0
- hydpy/cythons/autogen/c_meteo_temp_io.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_meteo_temp_io.pxd +112 -0
- hydpy/cythons/autogen/c_meteo_temp_io.pyx +176 -0
- hydpy/cythons/autogen/c_musk.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_musk.pxd +282 -0
- hydpy/cythons/autogen/c_musk.pyx +605 -0
- hydpy/cythons/autogen/c_musk_classic.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_musk_classic.pxd +138 -0
- hydpy/cythons/autogen/c_musk_classic.pyx +226 -0
- hydpy/cythons/autogen/c_musk_mct.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_musk_mct.pxd +282 -0
- hydpy/cythons/autogen/c_musk_mct.pyx +609 -0
- hydpy/cythons/autogen/c_rconc.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_rconc.pxd +119 -0
- hydpy/cythons/autogen/c_rconc.pyx +174 -0
- hydpy/cythons/autogen/c_rconc_nash.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_rconc_nash.pxd +111 -0
- hydpy/cythons/autogen/c_rconc_nash.pyx +185 -0
- hydpy/cythons/autogen/c_rconc_uh.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_rconc_uh.pxd +92 -0
- hydpy/cythons/autogen/c_rconc_uh.pyx +125 -0
- hydpy/cythons/autogen/c_sw1d.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_sw1d.pxd +511 -0
- hydpy/cythons/autogen/c_sw1d.pyx +1263 -0
- hydpy/cythons/autogen/c_sw1d_channel.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_sw1d_channel.pxd +119 -0
- hydpy/cythons/autogen/c_sw1d_channel.pyx +300 -0
- hydpy/cythons/autogen/c_sw1d_gate_out.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_sw1d_gate_out.pxd +240 -0
- hydpy/cythons/autogen/c_sw1d_gate_out.pyx +476 -0
- hydpy/cythons/autogen/c_sw1d_lias.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_sw1d_lias.pxd +320 -0
- hydpy/cythons/autogen/c_sw1d_lias.pyx +619 -0
- hydpy/cythons/autogen/c_sw1d_lias_sluice.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_sw1d_lias_sluice.pxd +325 -0
- hydpy/cythons/autogen/c_sw1d_lias_sluice.pyx +644 -0
- hydpy/cythons/autogen/c_sw1d_network.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_sw1d_network.pxd +90 -0
- hydpy/cythons/autogen/c_sw1d_network.pyx +246 -0
- hydpy/cythons/autogen/c_sw1d_pump.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_sw1d_pump.pxd +256 -0
- hydpy/cythons/autogen/c_sw1d_pump.pyx +502 -0
- hydpy/cythons/autogen/c_sw1d_q_in.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_sw1d_q_in.pxd +224 -0
- hydpy/cythons/autogen/c_sw1d_q_in.pyx +383 -0
- hydpy/cythons/autogen/c_sw1d_q_out.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_sw1d_q_out.pxd +224 -0
- hydpy/cythons/autogen/c_sw1d_q_out.pyx +383 -0
- hydpy/cythons/autogen/c_sw1d_storage.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_sw1d_storage.pxd +193 -0
- hydpy/cythons/autogen/c_sw1d_storage.pyx +349 -0
- hydpy/cythons/autogen/c_sw1d_weir_out.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_sw1d_weir_out.pxd +212 -0
- hydpy/cythons/autogen/c_sw1d_weir_out.pyx +404 -0
- hydpy/cythons/autogen/c_test.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_test.pxd +175 -0
- hydpy/cythons/autogen/c_test.pyx +348 -0
- hydpy/cythons/autogen/c_test_discontinous.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_test_discontinous.pxd +146 -0
- hydpy/cythons/autogen/c_test_discontinous.pyx +256 -0
- hydpy/cythons/autogen/c_test_stiff0d.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_test_stiff0d.pxd +146 -0
- hydpy/cythons/autogen/c_test_stiff0d.pyx +250 -0
- hydpy/cythons/autogen/c_test_stiff1d.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_test_stiff1d.pxd +145 -0
- hydpy/cythons/autogen/c_test_stiff1d.pyx +294 -0
- hydpy/cythons/autogen/c_whmod.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_whmod.pxd +482 -0
- hydpy/cythons/autogen/c_whmod.pyx +1156 -0
- hydpy/cythons/autogen/c_whmod_rural.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_whmod_rural.pxd +411 -0
- hydpy/cythons/autogen/c_whmod_rural.pyx +982 -0
- hydpy/cythons/autogen/c_whmod_urban.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_whmod_urban.pxd +482 -0
- hydpy/cythons/autogen/c_whmod_urban.pyx +1155 -0
- hydpy/cythons/autogen/c_wland.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_wland.pxd +842 -0
- hydpy/cythons/autogen/c_wland.pyx +1890 -0
- hydpy/cythons/autogen/c_wland_gd.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_wland_gd.pxd +829 -0
- hydpy/cythons/autogen/c_wland_gd.pyx +1847 -0
- hydpy/cythons/autogen/c_wland_wag.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_wland_wag.pxd +810 -0
- hydpy/cythons/autogen/c_wland_wag.pyx +1780 -0
- hydpy/cythons/autogen/c_wq.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_wq.pxd +275 -0
- hydpy/cythons/autogen/c_wq.pyx +652 -0
- hydpy/cythons/autogen/c_wq_trapeze.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_wq_trapeze.pxd +170 -0
- hydpy/cythons/autogen/c_wq_trapeze.pyx +400 -0
- hydpy/cythons/autogen/c_wq_trapeze_strickler.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_wq_trapeze_strickler.pxd +243 -0
- hydpy/cythons/autogen/c_wq_trapeze_strickler.pyx +578 -0
- hydpy/cythons/autogen/c_wq_walrus.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_wq_walrus.pxd +61 -0
- hydpy/cythons/autogen/c_wq_walrus.pyx +82 -0
- hydpy/cythons/autogen/configutils.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/configutils.pxd +17 -0
- hydpy/cythons/autogen/configutils.pyx +119 -0
- hydpy/cythons/autogen/interfaceutils.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/interfaceutils.pxd +31 -0
- hydpy/cythons/autogen/interfaceutils.pyx +82 -0
- hydpy/cythons/autogen/interputils.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/interputils.pxd +42 -0
- hydpy/cythons/autogen/interputils.pyx +118 -0
- hydpy/cythons/autogen/masterinterface.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/masterinterface.pxd +153 -0
- hydpy/cythons/autogen/masterinterface.pyx +222 -0
- hydpy/cythons/autogen/pointerutils.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/pointerutils.pxd +31 -0
- hydpy/cythons/autogen/pointerutils.pyx +650 -0
- hydpy/cythons/autogen/ppolyutils.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/ppolyutils.pxd +35 -0
- hydpy/cythons/autogen/ppolyutils.pyx +59 -0
- hydpy/cythons/autogen/quadutils.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/quadutils.pxd +26 -0
- hydpy/cythons/autogen/quadutils.pyx +973 -0
- hydpy/cythons/autogen/rootutils.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/rootutils.pxd +28 -0
- hydpy/cythons/autogen/rootutils.pyx +109 -0
- hydpy/cythons/autogen/sequenceutils.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/sequenceutils.pxd +45 -0
- hydpy/cythons/autogen/sequenceutils.pyx +101 -0
- hydpy/cythons/autogen/smoothutils.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/smoothutils.pxd +29 -0
- hydpy/cythons/autogen/smoothutils.pyx +833 -0
- hydpy/cythons/configutils.pxd +8 -0
- hydpy/cythons/configutils.pyi +5 -0
- hydpy/cythons/configutils.pyx +110 -0
- hydpy/cythons/interfaceutils.pxd +22 -0
- hydpy/cythons/interfaceutils.pyi +15 -0
- hydpy/cythons/interfaceutils.pyx +73 -0
- hydpy/cythons/interputils.pxd +33 -0
- hydpy/cythons/interputils.pyi +32 -0
- hydpy/cythons/interputils.pyx +109 -0
- hydpy/cythons/modelutils.py +2990 -0
- hydpy/cythons/pointerutils.pxd +22 -0
- hydpy/cythons/pointerutils.pyi +89 -0
- hydpy/cythons/pointerutils.pyx +641 -0
- hydpy/cythons/ppolyutils.pxd +26 -0
- hydpy/cythons/ppolyutils.pyi +21 -0
- hydpy/cythons/ppolyutils.pyx +50 -0
- hydpy/cythons/quadutils.pxd +17 -0
- hydpy/cythons/quadutils.pyi +13 -0
- hydpy/cythons/quadutils.pyx +964 -0
- hydpy/cythons/rootutils.pxd +19 -0
- hydpy/cythons/rootutils.pyi +21 -0
- hydpy/cythons/rootutils.pyx +100 -0
- hydpy/cythons/sequenceutils.pxd +36 -0
- hydpy/cythons/sequenceutils.pyi +7 -0
- hydpy/cythons/sequenceutils.pyx +92 -0
- hydpy/cythons/smoothutils.pxd +20 -0
- hydpy/cythons/smoothutils.pyi +15 -0
- hydpy/cythons/smoothutils.pyx +824 -0
- hydpy/data/HydPy-H-Lahn/conditions/init_1996_01_01_00_00_00/land_dill_assl.py +13 -0
- hydpy/data/HydPy-H-Lahn/conditions/init_1996_01_01_00_00_00/land_lahn_kalk.py +13 -0
- hydpy/data/HydPy-H-Lahn/conditions/init_1996_01_01_00_00_00/land_lahn_leun.py +14 -0
- hydpy/data/HydPy-H-Lahn/conditions/init_1996_01_01_00_00_00/land_lahn_marb.py +13 -0
- hydpy/data/HydPy-H-Lahn/conditions/init_1996_01_01_00_00_00/stream_dill_assl_lahn_leun.py +5 -0
- hydpy/data/HydPy-H-Lahn/conditions/init_1996_01_01_00_00_00/stream_lahn_leun_lahn_kalk.py +5 -0
- hydpy/data/HydPy-H-Lahn/conditions/init_1996_01_01_00_00_00/stream_lahn_marb_lahn_leun.py +5 -0
- hydpy/data/HydPy-H-Lahn/control/default/land.py +9 -0
- hydpy/data/HydPy-H-Lahn/control/default/land_dill_assl.py +57 -0
- hydpy/data/HydPy-H-Lahn/control/default/land_lahn_kalk.py +57 -0
- hydpy/data/HydPy-H-Lahn/control/default/land_lahn_leun.py +56 -0
- hydpy/data/HydPy-H-Lahn/control/default/land_lahn_marb.py +57 -0
- hydpy/data/HydPy-H-Lahn/control/default/stream_dill_assl_lahn_leun.py +7 -0
- hydpy/data/HydPy-H-Lahn/control/default/stream_lahn_leun_lahn_kalk.py +7 -0
- hydpy/data/HydPy-H-Lahn/control/default/stream_lahn_marb_lahn_leun.py +7 -0
- hydpy/data/HydPy-H-Lahn/multiple_runs.xml +309 -0
- hydpy/data/HydPy-H-Lahn/multiple_runs_alpha.xml +71 -0
- hydpy/data/HydPy-H-Lahn/network/default/headwaters.py +11 -0
- hydpy/data/HydPy-H-Lahn/network/default/nonheadwaters.py +11 -0
- hydpy/data/HydPy-H-Lahn/network/default/streams.py +8 -0
- hydpy/data/HydPy-H-Lahn/series/default/dill_assl_obs_q.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/evap_pet_hbv96_input_normalairtemperature.nc +0 -0
- hydpy/data/HydPy-H-Lahn/series/default/evap_pet_hbv96_input_normalevapotranspiration.nc +0 -0
- hydpy/data/HydPy-H-Lahn/series/default/hland_96_input_p.nc +0 -0
- hydpy/data/HydPy-H-Lahn/series/default/hland_96_input_t.nc +0 -0
- hydpy/data/HydPy-H-Lahn/series/default/lahn_kalk_obs_q.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/lahn_leun_obs_q.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/lahn_marb_obs_q.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/land_dill_assl_evap_pet_hbv96_input_normalairtemperature.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/land_dill_assl_evap_pet_hbv96_input_normalevapotranspiration.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/land_dill_assl_hland_96_input_p.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/land_dill_assl_hland_96_input_t.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/land_lahn_kalk_evap_pet_hbv96_input_normalairtemperature.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/land_lahn_kalk_evap_pet_hbv96_input_normalevapotranspiration.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/land_lahn_kalk_hland_96_input_p.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/land_lahn_kalk_hland_96_input_t.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/land_lahn_leun_evap_pet_hbv96_input_normalairtemperature.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/land_lahn_leun_evap_pet_hbv96_input_normalevapotranspiration.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/land_lahn_leun_hland_96_input_p.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/land_lahn_leun_hland_96_input_t.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/land_lahn_marb_evap_pet_hbv96_input_normalairtemperature.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/land_lahn_marb_evap_pet_hbv96_input_normalevapotranspiration.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/land_lahn_marb_hland_96_input_p.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/land_lahn_marb_hland_96_input_t.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/obs_q.nc +0 -0
- hydpy/data/HydPy-H-Lahn/single_run.xml +152 -0
- hydpy/data/HydPy-H-Lahn/single_run.xmlt +143 -0
- hydpy/data/__init__.py +17 -0
- hydpy/docs/__init__.py +0 -0
- hydpy/docs/autofigs/__init__.py +0 -0
- hydpy/docs/bib/__init__.py +0 -0
- hydpy/docs/bib/refs.bib +566 -0
- hydpy/docs/combine_docversions.py +133 -0
- hydpy/docs/draw_model_sketches.py +1301 -0
- hydpy/docs/enable_autodoc.py +7 -0
- hydpy/docs/figs/HydPy-G-GR4.png +0 -0
- hydpy/docs/figs/HydPy-G-GR5.png +0 -0
- hydpy/docs/figs/HydPy-G-GR6.png +0 -0
- hydpy/docs/figs/HydPy-H-HBV96-COSERO.png +0 -0
- hydpy/docs/figs/HydPy-H-HBV96-PREVAH.png +0 -0
- hydpy/docs/figs/HydPy-H-HBV96.png +0 -0
- hydpy/docs/figs/HydPy-H-Lahn.png +0 -0
- hydpy/docs/figs/HydPy-KinW-Williams.png +0 -0
- hydpy/docs/figs/HydPy-L-DD.png +0 -0
- hydpy/docs/figs/HydPy-W-Wag.png +0 -0
- hydpy/docs/figs/HydPy_Logo.png +0 -0
- hydpy/docs/figs/HydPy_Logo_Text.png +0 -0
- hydpy/docs/figs/IDLE-editor.png +0 -0
- hydpy/docs/figs/IDLE-shell.png +0 -0
- hydpy/docs/figs/LAWA_river-basin-bumbers.png +0 -0
- hydpy/docs/figs/__init__.py +0 -0
- hydpy/docs/html_/__init__.py +0 -0
- hydpy/docs/polish_html.py +57 -0
- hydpy/docs/prepare.py +224 -0
- hydpy/docs/publish_docs.py +53 -0
- hydpy/docs/rst/HydPy-ARMA.rst +27 -0
- hydpy/docs/rst/HydPy-Conv.rst +22 -0
- hydpy/docs/rst/HydPy-Dam.rst +79 -0
- hydpy/docs/rst/HydPy-Dummy.rst +21 -0
- hydpy/docs/rst/HydPy-Evap.rst +26 -0
- hydpy/docs/rst/HydPy-Exch.rst +36 -0
- hydpy/docs/rst/HydPy-G.rst +40 -0
- hydpy/docs/rst/HydPy-GA.rst +34 -0
- hydpy/docs/rst/HydPy-H.rst +24 -0
- hydpy/docs/rst/HydPy-KinW.rst +32 -0
- hydpy/docs/rst/HydPy-L.rst +42 -0
- hydpy/docs/rst/HydPy-Meteo.rst +28 -0
- hydpy/docs/rst/HydPy-Musk.rst +21 -0
- hydpy/docs/rst/HydPy-Rconc.rst +17 -0
- hydpy/docs/rst/HydPy-SW1D.rst +49 -0
- hydpy/docs/rst/HydPy-Test.rst +19 -0
- hydpy/docs/rst/HydPy-W.rst +20 -0
- hydpy/docs/rst/HydPy-WHMod.rst +19 -0
- hydpy/docs/rst/HydPy-WQ.rst +20 -0
- hydpy/docs/rst/__init__.py +0 -0
- hydpy/docs/rst/additional_repositories.rst +40 -0
- hydpy/docs/rst/auxiliaries.rst +31 -0
- hydpy/docs/rst/continuous_integration.rst +75 -0
- hydpy/docs/rst/core.rst +75 -0
- hydpy/docs/rst/cythons.rst +47 -0
- hydpy/docs/rst/definitions.rst +506 -0
- hydpy/docs/rst/developer_guide.rst +54 -0
- hydpy/docs/rst/example_projects.rst +40 -0
- hydpy/docs/rst/execution.rst +22 -0
- hydpy/docs/rst/framework_tools.rst +56 -0
- hydpy/docs/rst/how_to_read_the_reference_manual.rst +156 -0
- hydpy/docs/rst/hydpydependencies.rst +55 -0
- hydpy/docs/rst/index.rst +125 -0
- hydpy/docs/rst/installation.rst +155 -0
- hydpy/docs/rst/model_families.rst +79 -0
- hydpy/docs/rst/model_overview.rst +291 -0
- hydpy/docs/rst/modelimports.rst +10 -0
- hydpy/docs/rst/options.rst +119 -0
- hydpy/docs/rst/programming_style.rst +572 -0
- hydpy/docs/rst/project_structure.rst +520 -0
- hydpy/docs/rst/quickstart.rst +304 -0
- hydpy/docs/rst/reference_manual.rst +29 -0
- hydpy/docs/rst/required_tools.rst +50 -0
- hydpy/docs/rst/simulation.rst +514 -0
- hydpy/docs/rst/submodel_interfaces.rst +32 -0
- hydpy/docs/rst/tests_and_documentation.rst +85 -0
- hydpy/docs/rst/user_guide.rst +38 -0
- hydpy/docs/rst/version_control.rst +116 -0
- hydpy/docs/rst/zbibliography.rst +8 -0
- hydpy/docs/sphinx/__init__.py +0 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/changes/frameset.html +11 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/changes/rstsource.html +15 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/changes/versionchanges.html +33 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/defindex.html +35 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/domainindex.html +56 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/genindex-single.html +63 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/genindex-split.html +41 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/genindex.html +76 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/globaltoc.html +11 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/layout.html +221 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/localtoc.html +15 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/opensearch.xml +13 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/page.html +13 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/relations.html +23 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/search.html +65 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/searchbox.html +21 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/searchfield.html +23 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/sourcelink.html +18 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/static/basic.css_t +925 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/static/doctools.js +156 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/static/documentation_options.js_t +13 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/static/file.png +0 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/static/language_data.js_t +26 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/static/minus.png +0 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/static/plus.png +0 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/static/searchtools.js +574 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/static/sphinx_highlight.js +154 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/theme.conf +16 -0
- hydpy/docs/sphinx/_themes/classic_hydpy/layout.html +23 -0
- hydpy/docs/sphinx/_themes/classic_hydpy/static/classic.css_t +358 -0
- hydpy/docs/sphinx/_themes/classic_hydpy/static/sidebar.js_t +72 -0
- hydpy/docs/sphinx/_themes/classic_hydpy/theme.conf +32 -0
- hydpy/docs/sphinx/conf.py +398 -0
- hydpy/docs/sphinx/defaultlinks_extension.py +36 -0
- hydpy/docs/sphinx/integrationtest_extension.py +104 -0
- hydpy/docs/sphinx/projectstructure_extension.py +58 -0
- hydpy/docs/sphinx/submodelgraph_extension.py +53 -0
- hydpy/exe/__init__.py +0 -0
- hydpy/exe/commandtools.py +651 -0
- hydpy/exe/hyd.py +277 -0
- hydpy/exe/modelimports.py +41 -0
- hydpy/exe/replacetools.py +216 -0
- hydpy/exe/servertools.py +2348 -0
- hydpy/exe/xmltools.py +3280 -0
- hydpy/interfaces/__init__.py +0 -0
- hydpy/interfaces/aetinterfaces.py +94 -0
- hydpy/interfaces/dischargeinterfaces.py +45 -0
- hydpy/interfaces/petinterfaces.py +117 -0
- hydpy/interfaces/precipinterfaces.py +42 -0
- hydpy/interfaces/radiationinterfaces.py +79 -0
- hydpy/interfaces/rconcinterfaces.py +30 -0
- hydpy/interfaces/routinginterfaces.py +324 -0
- hydpy/interfaces/soilinterfaces.py +96 -0
- hydpy/interfaces/stateinterfaces.py +98 -0
- hydpy/interfaces/tempinterfaces.py +46 -0
- hydpy/models/__init__.py +0 -0
- hydpy/models/arma/__init__.py +14 -0
- hydpy/models/arma/arma_control.py +383 -0
- hydpy/models/arma/arma_derived.py +204 -0
- hydpy/models/arma/arma_fluxes.py +41 -0
- hydpy/models/arma/arma_inlets.py +11 -0
- hydpy/models/arma/arma_logs.py +19 -0
- hydpy/models/arma/arma_model.py +461 -0
- hydpy/models/arma/arma_outlets.py +11 -0
- hydpy/models/arma_rimorido.py +381 -0
- hydpy/models/conv/__init__.py +12 -0
- hydpy/models/conv/conv_control.py +303 -0
- hydpy/models/conv/conv_derived.py +271 -0
- hydpy/models/conv/conv_fluxes.py +54 -0
- hydpy/models/conv/conv_inlets.py +11 -0
- hydpy/models/conv/conv_model.py +687 -0
- hydpy/models/conv/conv_outlets.py +11 -0
- hydpy/models/conv_idw.py +120 -0
- hydpy/models/conv_idw_ed.py +184 -0
- hydpy/models/conv_nn.py +112 -0
- hydpy/models/dam/__init__.py +16 -0
- hydpy/models/dam/dam_aides.py +17 -0
- hydpy/models/dam/dam_control.py +346 -0
- hydpy/models/dam/dam_derived.py +559 -0
- hydpy/models/dam/dam_factors.py +46 -0
- hydpy/models/dam/dam_fluxes.py +179 -0
- hydpy/models/dam/dam_inlets.py +29 -0
- hydpy/models/dam/dam_logs.py +52 -0
- hydpy/models/dam/dam_model.py +5011 -0
- hydpy/models/dam/dam_outlets.py +23 -0
- hydpy/models/dam/dam_receivers.py +41 -0
- hydpy/models/dam/dam_senders.py +23 -0
- hydpy/models/dam/dam_solver.py +75 -0
- hydpy/models/dam/dam_states.py +11 -0
- hydpy/models/dam_llake.py +499 -0
- hydpy/models/dam_lreservoir.py +548 -0
- hydpy/models/dam_lretention.py +343 -0
- hydpy/models/dam_pump.py +278 -0
- hydpy/models/dam_pump_sluice.py +339 -0
- hydpy/models/dam_sluice.py +319 -0
- hydpy/models/dam_v001.py +1127 -0
- hydpy/models/dam_v002.py +381 -0
- hydpy/models/dam_v003.py +422 -0
- hydpy/models/dam_v004.py +665 -0
- hydpy/models/dam_v005.py +479 -0
- hydpy/models/dummy/__init__.py +15 -0
- hydpy/models/dummy/dummy_control.py +22 -0
- hydpy/models/dummy/dummy_fluxes.py +11 -0
- hydpy/models/dummy/dummy_inlets.py +11 -0
- hydpy/models/dummy/dummy_inputs.py +41 -0
- hydpy/models/dummy/dummy_model.py +196 -0
- hydpy/models/dummy/dummy_outlets.py +11 -0
- hydpy/models/dummy_interceptedwater.py +85 -0
- hydpy/models/dummy_node2node.py +83 -0
- hydpy/models/dummy_snowalbedo.py +84 -0
- hydpy/models/dummy_snowcover.py +84 -0
- hydpy/models/dummy_snowycanopy.py +86 -0
- hydpy/models/dummy_soilwater.py +85 -0
- hydpy/models/evap/__init__.py +13 -0
- hydpy/models/evap/evap_control.py +354 -0
- hydpy/models/evap/evap_derived.py +236 -0
- hydpy/models/evap/evap_factors.py +188 -0
- hydpy/models/evap/evap_fixed.py +68 -0
- hydpy/models/evap/evap_fluxes.py +150 -0
- hydpy/models/evap/evap_inputs.py +54 -0
- hydpy/models/evap/evap_logs.py +91 -0
- hydpy/models/evap/evap_masks.py +48 -0
- hydpy/models/evap/evap_model.py +9170 -0
- hydpy/models/evap/evap_parameters.py +149 -0
- hydpy/models/evap/evap_sequences.py +32 -0
- hydpy/models/evap/evap_states.py +18 -0
- hydpy/models/evap_aet_hbv96.py +372 -0
- hydpy/models/evap_aet_minhas.py +331 -0
- hydpy/models/evap_aet_morsim.py +627 -0
- hydpy/models/evap_pet_ambav1.py +483 -0
- hydpy/models/evap_pet_hbv96.py +147 -0
- hydpy/models/evap_pet_m.py +94 -0
- hydpy/models/evap_pet_mlc.py +107 -0
- hydpy/models/evap_ret_fao56.py +265 -0
- hydpy/models/evap_ret_io.py +74 -0
- hydpy/models/evap_ret_tw2002.py +165 -0
- hydpy/models/exch/__init__.py +14 -0
- hydpy/models/exch/exch_control.py +262 -0
- hydpy/models/exch/exch_derived.py +36 -0
- hydpy/models/exch/exch_factors.py +26 -0
- hydpy/models/exch/exch_fluxes.py +48 -0
- hydpy/models/exch/exch_inlets.py +11 -0
- hydpy/models/exch/exch_logs.py +12 -0
- hydpy/models/exch/exch_model.py +451 -0
- hydpy/models/exch/exch_outlets.py +17 -0
- hydpy/models/exch/exch_receivers.py +17 -0
- hydpy/models/exch_branch_hbv96.py +186 -0
- hydpy/models/exch_waterlevel.py +73 -0
- hydpy/models/exch_weir_hbv96.py +609 -0
- hydpy/models/ga/__init__.py +14 -0
- hydpy/models/ga/ga_aides.py +17 -0
- hydpy/models/ga/ga_control.py +208 -0
- hydpy/models/ga/ga_derived.py +77 -0
- hydpy/models/ga/ga_fluxes.py +83 -0
- hydpy/models/ga/ga_inputs.py +26 -0
- hydpy/models/ga/ga_logs.py +17 -0
- hydpy/models/ga/ga_model.py +2952 -0
- hydpy/models/ga/ga_states.py +87 -0
- hydpy/models/ga_garto.py +1001 -0
- hydpy/models/ga_garto_submodel1.py +79 -0
- hydpy/models/gland/__init__.py +14 -0
- hydpy/models/gland/gland_control.py +90 -0
- hydpy/models/gland/gland_derived.py +113 -0
- hydpy/models/gland/gland_fluxes.py +137 -0
- hydpy/models/gland/gland_inputs.py +12 -0
- hydpy/models/gland/gland_model.py +1439 -0
- hydpy/models/gland/gland_outlets.py +11 -0
- hydpy/models/gland/gland_states.py +90 -0
- hydpy/models/gland_gr4.py +501 -0
- hydpy/models/gland_gr5.py +463 -0
- hydpy/models/gland_gr6.py +487 -0
- hydpy/models/hland/__init__.py +20 -0
- hydpy/models/hland/hland_aides.py +19 -0
- hydpy/models/hland/hland_constants.py +37 -0
- hydpy/models/hland/hland_control.py +1530 -0
- hydpy/models/hland/hland_derived.py +683 -0
- hydpy/models/hland/hland_factors.py +57 -0
- hydpy/models/hland/hland_fixed.py +42 -0
- hydpy/models/hland/hland_fluxes.py +279 -0
- hydpy/models/hland/hland_inputs.py +19 -0
- hydpy/models/hland/hland_masks.py +107 -0
- hydpy/models/hland/hland_model.py +4664 -0
- hydpy/models/hland/hland_outlets.py +11 -0
- hydpy/models/hland/hland_parameters.py +227 -0
- hydpy/models/hland/hland_sequences.py +382 -0
- hydpy/models/hland/hland_states.py +236 -0
- hydpy/models/hland_96.py +1812 -0
- hydpy/models/hland_96c.py +1196 -0
- hydpy/models/hland_96p.py +1204 -0
- hydpy/models/kinw/__init__.py +18 -0
- hydpy/models/kinw/kinw_aides.py +306 -0
- hydpy/models/kinw/kinw_control.py +270 -0
- hydpy/models/kinw/kinw_derived.py +197 -0
- hydpy/models/kinw/kinw_fixed.py +33 -0
- hydpy/models/kinw/kinw_fluxes.py +37 -0
- hydpy/models/kinw/kinw_inlets.py +11 -0
- hydpy/models/kinw/kinw_model.py +3026 -0
- hydpy/models/kinw/kinw_outlets.py +11 -0
- hydpy/models/kinw/kinw_solver.py +45 -0
- hydpy/models/kinw/kinw_states.py +17 -0
- hydpy/models/kinw_williams.py +1299 -0
- hydpy/models/kinw_williams_ext.py +768 -0
- hydpy/models/lland/__init__.py +42 -0
- hydpy/models/lland/lland_aides.py +38 -0
- hydpy/models/lland/lland_constants.py +88 -0
- hydpy/models/lland/lland_control.py +1329 -0
- hydpy/models/lland/lland_derived.py +380 -0
- hydpy/models/lland/lland_factors.py +18 -0
- hydpy/models/lland/lland_fixed.py +128 -0
- hydpy/models/lland/lland_fluxes.py +626 -0
- hydpy/models/lland/lland_inlets.py +12 -0
- hydpy/models/lland/lland_inputs.py +33 -0
- hydpy/models/lland/lland_logs.py +17 -0
- hydpy/models/lland/lland_masks.py +212 -0
- hydpy/models/lland/lland_model.py +7690 -0
- hydpy/models/lland/lland_outlets.py +12 -0
- hydpy/models/lland/lland_parameters.py +195 -0
- hydpy/models/lland/lland_sequences.py +67 -0
- hydpy/models/lland/lland_states.py +280 -0
- hydpy/models/lland_dd.py +2270 -0
- hydpy/models/lland_knauf.py +2156 -0
- hydpy/models/lland_knauf_ic.py +1920 -0
- hydpy/models/meteo/__init__.py +12 -0
- hydpy/models/meteo/meteo_control.py +154 -0
- hydpy/models/meteo/meteo_derived.py +159 -0
- hydpy/models/meteo/meteo_factors.py +88 -0
- hydpy/models/meteo/meteo_fixed.py +19 -0
- hydpy/models/meteo/meteo_fluxes.py +46 -0
- hydpy/models/meteo/meteo_inputs.py +47 -0
- hydpy/models/meteo/meteo_logs.py +30 -0
- hydpy/models/meteo/meteo_model.py +2904 -0
- hydpy/models/meteo/meteo_parameters.py +14 -0
- hydpy/models/meteo/meteo_sequences.py +22 -0
- hydpy/models/meteo_clear_glob_io.py +77 -0
- hydpy/models/meteo_glob_fao56.py +217 -0
- hydpy/models/meteo_glob_io.py +68 -0
- hydpy/models/meteo_glob_morsim.py +444 -0
- hydpy/models/meteo_precip_io.py +76 -0
- hydpy/models/meteo_psun_sun_glob_io.py +83 -0
- hydpy/models/meteo_sun_fao56.py +188 -0
- hydpy/models/meteo_sun_morsim.py +466 -0
- hydpy/models/meteo_temp_io.py +76 -0
- hydpy/models/musk/__init__.py +15 -0
- hydpy/models/musk/musk_control.py +328 -0
- hydpy/models/musk/musk_derived.py +32 -0
- hydpy/models/musk/musk_factors.py +53 -0
- hydpy/models/musk/musk_fluxes.py +24 -0
- hydpy/models/musk/musk_inlets.py +11 -0
- hydpy/models/musk/musk_masks.py +15 -0
- hydpy/models/musk/musk_model.py +838 -0
- hydpy/models/musk/musk_outlets.py +11 -0
- hydpy/models/musk/musk_sequences.py +88 -0
- hydpy/models/musk/musk_solver.py +68 -0
- hydpy/models/musk/musk_states.py +64 -0
- hydpy/models/musk_classic.py +228 -0
- hydpy/models/musk_mct.py +1247 -0
- hydpy/models/rconc/__init__.py +12 -0
- hydpy/models/rconc/rconc_control.py +473 -0
- hydpy/models/rconc/rconc_derived.py +76 -0
- hydpy/models/rconc/rconc_fluxes.py +19 -0
- hydpy/models/rconc/rconc_logs.py +74 -0
- hydpy/models/rconc/rconc_model.py +260 -0
- hydpy/models/rconc/rconc_states.py +11 -0
- hydpy/models/rconc_nash.py +48 -0
- hydpy/models/rconc_uh.py +53 -0
- hydpy/models/sw1d/__init__.py +17 -0
- hydpy/models/sw1d/sw1d_control.py +356 -0
- hydpy/models/sw1d/sw1d_derived.py +85 -0
- hydpy/models/sw1d/sw1d_factors.py +78 -0
- hydpy/models/sw1d/sw1d_fixed.py +12 -0
- hydpy/models/sw1d/sw1d_fluxes.py +55 -0
- hydpy/models/sw1d/sw1d_inlets.py +17 -0
- hydpy/models/sw1d/sw1d_model.py +3385 -0
- hydpy/models/sw1d/sw1d_outlets.py +11 -0
- hydpy/models/sw1d/sw1d_receivers.py +11 -0
- hydpy/models/sw1d/sw1d_senders.py +11 -0
- hydpy/models/sw1d/sw1d_states.py +23 -0
- hydpy/models/sw1d_channel.py +2051 -0
- hydpy/models/sw1d_gate_out.py +599 -0
- hydpy/models/sw1d_lias.py +105 -0
- hydpy/models/sw1d_lias_sluice.py +531 -0
- hydpy/models/sw1d_network.py +1219 -0
- hydpy/models/sw1d_pump.py +448 -0
- hydpy/models/sw1d_q_in.py +79 -0
- hydpy/models/sw1d_q_out.py +81 -0
- hydpy/models/sw1d_storage.py +78 -0
- hydpy/models/sw1d_weir_out.py +75 -0
- hydpy/models/test/__init__.py +14 -0
- hydpy/models/test/test_control.py +28 -0
- hydpy/models/test/test_fluxes.py +17 -0
- hydpy/models/test/test_model.py +201 -0
- hydpy/models/test/test_solver.py +48 -0
- hydpy/models/test/test_states.py +17 -0
- hydpy/models/test_discontinous.py +46 -0
- hydpy/models/test_stiff0d.py +47 -0
- hydpy/models/test_stiff1d.py +42 -0
- hydpy/models/whmod/__init__.py +21 -0
- hydpy/models/whmod/whmod_constants.py +77 -0
- hydpy/models/whmod/whmod_control.py +333 -0
- hydpy/models/whmod/whmod_derived.py +210 -0
- hydpy/models/whmod/whmod_factors.py +9 -0
- hydpy/models/whmod/whmod_fluxes.py +105 -0
- hydpy/models/whmod/whmod_inputs.py +15 -0
- hydpy/models/whmod/whmod_masks.py +178 -0
- hydpy/models/whmod/whmod_model.py +2091 -0
- hydpy/models/whmod/whmod_parameters.py +155 -0
- hydpy/models/whmod/whmod_sequences.py +193 -0
- hydpy/models/whmod/whmod_states.py +73 -0
- hydpy/models/whmod_rural.py +794 -0
- hydpy/models/whmod_urban.py +1011 -0
- hydpy/models/wland/__init__.py +43 -0
- hydpy/models/wland/wland_aides.py +55 -0
- hydpy/models/wland/wland_constants.py +103 -0
- hydpy/models/wland/wland_control.py +508 -0
- hydpy/models/wland/wland_derived.py +330 -0
- hydpy/models/wland/wland_factors.py +11 -0
- hydpy/models/wland/wland_fixed.py +12 -0
- hydpy/models/wland/wland_fluxes.py +166 -0
- hydpy/models/wland/wland_inputs.py +33 -0
- hydpy/models/wland/wland_masks.py +54 -0
- hydpy/models/wland/wland_model.py +3755 -0
- hydpy/models/wland/wland_outlets.py +11 -0
- hydpy/models/wland/wland_parameters.py +214 -0
- hydpy/models/wland/wland_sequences.py +108 -0
- hydpy/models/wland/wland_solver.py +45 -0
- hydpy/models/wland/wland_states.py +56 -0
- hydpy/models/wland_gd.py +888 -0
- hydpy/models/wland_wag.py +1244 -0
- hydpy/models/wq/__init__.py +14 -0
- hydpy/models/wq/wq_control.py +117 -0
- hydpy/models/wq/wq_derived.py +182 -0
- hydpy/models/wq/wq_factors.py +79 -0
- hydpy/models/wq/wq_fluxes.py +17 -0
- hydpy/models/wq/wq_model.py +1889 -0
- hydpy/models/wq_trapeze.py +168 -0
- hydpy/models/wq_trapeze_strickler.py +101 -0
- hydpy/models/wq_walrus.py +57 -0
- hydpy/py.typed +0 -0
- hydpy/tests/.coveragerc +22 -0
- hydpy/tests/__init__.py +0 -0
- hydpy/tests/check_consistency.py +32 -0
- hydpy/tests/hydpydoctestcustomize.pth +1 -0
- hydpy/tests/hydpydoctestcustomize.py +15 -0
- hydpy/tests/iotesting/__init__.py +0 -0
- hydpy/tests/run_doctests.py +233 -0
- hydpy-6.2.dev1.data/scripts/hyd.py +277 -0
- hydpy-6.2.dev1.dist-info/LICENSE +165 -0
- hydpy-6.2.dev1.dist-info/METADATA +163 -0
- hydpy-6.2.dev1.dist-info/RECORD +890 -0
- hydpy-6.2.dev1.dist-info/WHEEL +5 -0
- hydpy-6.2.dev1.dist-info/licenses_hydpy_installer.txt +42 -0
- hydpy-6.2.dev1.dist-info/top_level.txt +1 -0
hydpy/auxs/anntools.py
ADDED
|
@@ -0,0 +1,1305 @@
|
|
|
1
|
+
"""This module implements rudimentary artificial neural network tools required for some
|
|
2
|
+
models implemented in the *HydPy* framework.
|
|
3
|
+
|
|
4
|
+
The relevant models apply some of the neural network features during simulation runs,
|
|
5
|
+
which is why we implement these features in the Cython extension module |annutils|.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
# import...
|
|
9
|
+
# ...from standard library
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
import weakref
|
|
12
|
+
|
|
13
|
+
# ...from site-packages
|
|
14
|
+
import numpy
|
|
15
|
+
|
|
16
|
+
# ...from HydPy
|
|
17
|
+
from hydpy import config
|
|
18
|
+
from hydpy.core import objecttools
|
|
19
|
+
from hydpy.core import propertytools
|
|
20
|
+
from hydpy.core.typingtools import *
|
|
21
|
+
from hydpy.auxs import interptools
|
|
22
|
+
|
|
23
|
+
if TYPE_CHECKING:
|
|
24
|
+
from hydpy.cythons import annutils
|
|
25
|
+
else:
|
|
26
|
+
from hydpy.cythons.autogen import annutils
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class _ANNArrayProperty(propertytools.DependentProperty[T_contra, T_co]):
|
|
30
|
+
_obj2cann: weakref.WeakKeyDictionary[Any, annutils.ANN] = (
|
|
31
|
+
weakref.WeakKeyDictionary()
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
def __init__(self, protected: propertytools.ProtectedProperties, doc: str) -> None:
|
|
35
|
+
super().__init__(
|
|
36
|
+
protected=protected, fget=self._fget, fset=self._fset, fdel=self._fdel
|
|
37
|
+
)
|
|
38
|
+
self.set_doc(doc)
|
|
39
|
+
|
|
40
|
+
@classmethod
|
|
41
|
+
def add_cann(cls, obj: Any, cann: annutils.ANN) -> None:
|
|
42
|
+
"""Log the given Cython based ANN for the given object."""
|
|
43
|
+
cls._obj2cann[obj] = cann
|
|
44
|
+
|
|
45
|
+
@property
|
|
46
|
+
def _shape(self) -> str:
|
|
47
|
+
return f"shape_{self.name}"
|
|
48
|
+
|
|
49
|
+
def _fget(self, obj: ANN) -> T_co:
|
|
50
|
+
cann = self._obj2cann[obj]
|
|
51
|
+
return numpy.asarray(getattr(cann, self.name)) # type: ignore[return-value]
|
|
52
|
+
|
|
53
|
+
def _fset(self, obj: ANN, value: T_contra | None) -> None:
|
|
54
|
+
if value is None:
|
|
55
|
+
self.fdel(obj)
|
|
56
|
+
else:
|
|
57
|
+
try:
|
|
58
|
+
cann = self._obj2cann[obj]
|
|
59
|
+
shape = getattr(obj, self._shape)
|
|
60
|
+
if self.name == "activation":
|
|
61
|
+
array = numpy.full(shape, value, dtype=config.NP_INT)
|
|
62
|
+
else:
|
|
63
|
+
array = numpy.full(shape, value, dtype=config.NP_FLOAT)
|
|
64
|
+
setattr(cann, self.name, array)
|
|
65
|
+
except BaseException:
|
|
66
|
+
descr = " ".join(reversed(self.name.split("_")))
|
|
67
|
+
objecttools.augment_excmessage(
|
|
68
|
+
f"While trying to set the {descr} of the artificial neural "
|
|
69
|
+
f"network {objecttools.elementphrase(obj)}"
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
def _fdel(self, obj: ANN) -> None:
|
|
73
|
+
cann = self._obj2cann[obj]
|
|
74
|
+
if self.name == "activation":
|
|
75
|
+
array = numpy.ones(getattr(obj, self._shape), dtype=config.NP_INT)
|
|
76
|
+
else:
|
|
77
|
+
array = numpy.zeros(getattr(obj, self._shape), dtype=config.NP_FLOAT)
|
|
78
|
+
setattr(cann, self.name, array)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class ANN(interptools.InterpAlgorithm):
|
|
82
|
+
"""Multi-layer feed-forward artificial neural network.
|
|
83
|
+
|
|
84
|
+
By default, class |ANN| uses the logistic function
|
|
85
|
+
:math:`f(x) = \\frac{1}{1+exp(-x)}` to calculate the activation of the hidden
|
|
86
|
+
layer's neurons. Alternatively, one can select the identity function
|
|
87
|
+
:math:`f(x) = x` or a variant of the logistic function for filtering specific
|
|
88
|
+
inputs. See property |ANN.activation| for more information on how to do this.
|
|
89
|
+
|
|
90
|
+
You can select |ANN| as the interpolation algorithm used by |SimpleInterpolator| or
|
|
91
|
+
one of the interpolation algorithms used by |SeasonalInterpolator|. Its original
|
|
92
|
+
purpose was to define arbitrary continuous relationships between the water stored
|
|
93
|
+
in a dam and the associated water stage (see model |dam_v001|). However, class
|
|
94
|
+
|ANN| can also be applied directly for testing purposes, as shown in the following
|
|
95
|
+
examples.
|
|
96
|
+
|
|
97
|
+
First, define the most simple artificial neural network consisting of only one
|
|
98
|
+
input node, one hidden neuron, and one output node, and pass arbitrary values for
|
|
99
|
+
the weights and intercepts:
|
|
100
|
+
|
|
101
|
+
>>> from hydpy import ANN, nan
|
|
102
|
+
>>> ann = ANN(nmb_inputs=1, nmb_neurons=(1,), nmb_outputs=1,
|
|
103
|
+
... weights_input=4.0, weights_output=3.0,
|
|
104
|
+
... intercepts_hidden=-16.0, intercepts_output=-1.0)
|
|
105
|
+
|
|
106
|
+
The following loop subsequently sets the values 0 to 8 as input values, performs
|
|
107
|
+
the calculation, and prints out the final output. As to be expected, the results
|
|
108
|
+
show the shape of the logistic function:
|
|
109
|
+
|
|
110
|
+
>>> from hydpy import round_
|
|
111
|
+
>>> for input_ in range(9):
|
|
112
|
+
... ann.inputs[0] = input_
|
|
113
|
+
... ann.calculate_values()
|
|
114
|
+
... round_([input_, ann.outputs[0]])
|
|
115
|
+
0, -1.0
|
|
116
|
+
1, -0.999982
|
|
117
|
+
2, -0.998994
|
|
118
|
+
3, -0.946041
|
|
119
|
+
4, 0.5
|
|
120
|
+
5, 1.946041
|
|
121
|
+
6, 1.998994
|
|
122
|
+
7, 1.999982
|
|
123
|
+
8, 2.0
|
|
124
|
+
|
|
125
|
+
One can also directly plot the resulting graph:
|
|
126
|
+
|
|
127
|
+
>>> figure = ann.plot(0.0, 8.0)
|
|
128
|
+
|
|
129
|
+
You can use the `pyplot` API of `matplotlib` to modify the figure or to save it to
|
|
130
|
+
disk (or print it to the screen, in case the interactive mode of `matplotlib` is
|
|
131
|
+
disabled):
|
|
132
|
+
|
|
133
|
+
>>> from hydpy.core.testtools import save_autofig
|
|
134
|
+
>>> save_autofig("ANN_plot.png", figure=figure)
|
|
135
|
+
|
|
136
|
+
.. image:: ANN_plot.png
|
|
137
|
+
|
|
138
|
+
Some models might require the derivative of certain outputs with respect to
|
|
139
|
+
individual inputs. One example is application model the |dam_llake|, which uses
|
|
140
|
+
class |ANN| to model the relationship between water storage and stage of a lake.
|
|
141
|
+
During a simulation run , it additionally needs to know the area of the water
|
|
142
|
+
surface, which is the derivative of storage with respect to stage. For such
|
|
143
|
+
purposes, class |ANN| provides method |ANN.calculate_derivatives|. In the
|
|
144
|
+
following example, we apply this method and compare its results with finite
|
|
145
|
+
difference approximations:
|
|
146
|
+
|
|
147
|
+
>>> d_input = 1e-8
|
|
148
|
+
>>> for input_ in range(9):
|
|
149
|
+
... ann.inputs[0] = input_-d_input/2.0
|
|
150
|
+
... ann.calculate_values()
|
|
151
|
+
... value0 = ann.outputs[0]
|
|
152
|
+
... ann.inputs[0] = input_+d_input/2.0
|
|
153
|
+
... ann.calculate_values()
|
|
154
|
+
... value1 = ann.outputs[0]
|
|
155
|
+
... derivative = (value1-value0)/d_input
|
|
156
|
+
... ann.inputs[0] = input_
|
|
157
|
+
... ann.calculate_values()
|
|
158
|
+
... ann.calculate_derivatives(0)
|
|
159
|
+
... round_([input_, derivative, ann.output_derivatives[0]])
|
|
160
|
+
0, 0.000001, 0.000001
|
|
161
|
+
1, 0.000074, 0.000074
|
|
162
|
+
2, 0.004023, 0.004023
|
|
163
|
+
3, 0.211952, 0.211952
|
|
164
|
+
4, 3.0, 3.0
|
|
165
|
+
5, 0.211952, 0.211952
|
|
166
|
+
6, 0.004023, 0.004023
|
|
167
|
+
7, 0.000074, 0.000074
|
|
168
|
+
8, 0.000001, 0.000001
|
|
169
|
+
|
|
170
|
+
Note the following two potential pitfalls (both due to speeding up method
|
|
171
|
+
|ANN.calculate_derivatives|). First, for networks with more than one hidden layer,
|
|
172
|
+
you must call |ANN.calculate_values| before calling |ANN.calculate_derivatives|.
|
|
173
|
+
Second, method |ANN.calculate_derivatives| calculates the derivatives with respect
|
|
174
|
+
to a single input only, selected by the `idx_input` argument. However, it works
|
|
175
|
+
fine to call method |ANN.calculate_values| and then |ANN.calculate_derivatives|
|
|
176
|
+
multiple times afterwards. Thereby, you can subsequently pass different index
|
|
177
|
+
values to calculate the derivatives with respect to different inputs.
|
|
178
|
+
|
|
179
|
+
The following example shows that everything works well for more complex single
|
|
180
|
+
layer networks (we checked the results manually):
|
|
181
|
+
|
|
182
|
+
>>> ann.nmb_inputs = 3
|
|
183
|
+
>>> ann.nmb_neurons = (4,)
|
|
184
|
+
>>> ann.nmb_outputs = 2
|
|
185
|
+
>>> ann.weights_input = [[ 0.2, -0.1, -1.7, 0.6],
|
|
186
|
+
... [ 0.9, 0.2, 0.8, 0.0],
|
|
187
|
+
... [-0.5, -1.0, 2.3, -0.4]]
|
|
188
|
+
>>> ann.weights_output = [[ 0.0, 2.0],
|
|
189
|
+
... [-0.5, 1.0],
|
|
190
|
+
... [ 0.4, 2.4],
|
|
191
|
+
... [ 0.8, -0.9]]
|
|
192
|
+
>>> ann.intercepts_hidden = [ 0.9, 0.0, -0.4, -0.2]
|
|
193
|
+
>>> ann.intercepts_output = [ 1.3, -2.0]
|
|
194
|
+
>>> ann.inputs = [-0.1, 1.3, 1.6]
|
|
195
|
+
>>> ann.calculate_values()
|
|
196
|
+
>>> round_(ann.outputs)
|
|
197
|
+
1.822222, 1.876983
|
|
198
|
+
|
|
199
|
+
We again validate the calculated derivatives by comparison with numerical
|
|
200
|
+
approximations:
|
|
201
|
+
|
|
202
|
+
>>> for idx_input in range(3):
|
|
203
|
+
... ann.calculate_derivatives(idx_input)
|
|
204
|
+
... round_(ann.output_derivatives)
|
|
205
|
+
0.099449, -0.103039
|
|
206
|
+
-0.01303, 0.365739
|
|
207
|
+
0.027041, -0.203965
|
|
208
|
+
|
|
209
|
+
>>> d_input = 1e-8
|
|
210
|
+
>>> for idx_input in range(3):
|
|
211
|
+
... input_ = ann.inputs[idx_input]
|
|
212
|
+
... ann.inputs[idx_input] = input_-d_input/2.0
|
|
213
|
+
... ann.calculate_values()
|
|
214
|
+
... values0 = ann.outputs.copy()
|
|
215
|
+
... ann.inputs[idx_input] = input_+d_input/2.0
|
|
216
|
+
... ann.calculate_values()
|
|
217
|
+
... values1 = ann.outputs.copy()
|
|
218
|
+
... ann.inputs[idx_input] = input_
|
|
219
|
+
... round_((values1-values0)/d_input)
|
|
220
|
+
0.099449, -0.103039
|
|
221
|
+
-0.01303, 0.365739
|
|
222
|
+
0.027041, -0.203965
|
|
223
|
+
|
|
224
|
+
The next example shows how to solve the XOR problem with a two-layer network. As
|
|
225
|
+
usual, `1` stands for `True` and `0` stands for `False`.
|
|
226
|
+
|
|
227
|
+
We define a network with two inputs (`I1` and `I2`), two neurons in mthe first
|
|
228
|
+
hidden layer (`H11` and `H12`), one neuron in the second hidden layer (`H2`), and a
|
|
229
|
+
single output (`O1`):
|
|
230
|
+
|
|
231
|
+
>>> ann.nmb_inputs = 2
|
|
232
|
+
>>> ann.nmb_neurons = (2, 1)
|
|
233
|
+
>>> ann.nmb_outputs = 1
|
|
234
|
+
|
|
235
|
+
The value of `O1` shall be identical with the activation of `H2`:
|
|
236
|
+
|
|
237
|
+
>>> ann.weights_output = 1.0
|
|
238
|
+
>>> ann.intercepts_output = 0.0
|
|
239
|
+
|
|
240
|
+
We set all intercepts of the hidden layer's neurons to 750 and initialise
|
|
241
|
+
unnecessary matrix entries with "nan". So, an input of 500 or 1000 results in an
|
|
242
|
+
activation state of approximately zero or one, respectively:
|
|
243
|
+
|
|
244
|
+
>>> ann.intercepts_hidden = [[-750.0, -750.0],
|
|
245
|
+
... [-750.0, nan]]
|
|
246
|
+
|
|
247
|
+
The weighting factor between both inputs and `H11` is 1000. Hence, one `True`
|
|
248
|
+
input is sufficient to activate `H1`. In contrast, the weighting factor between
|
|
249
|
+
both inputs and `H12` is 500. Hence, two `True` inputs are required to activate
|
|
250
|
+
`H12`:
|
|
251
|
+
|
|
252
|
+
>>> ann.weights_input= [[1000.0, 500.0],
|
|
253
|
+
... [1000.0, 500.0]]
|
|
254
|
+
|
|
255
|
+
The weighting factor between `H11` and `H2` is 1000. Hence, in principle, `H11`
|
|
256
|
+
can activate `H2`. However, the weighting factor between `H12` and `H2` is -1000.
|
|
257
|
+
Hence, `H12` prevents `H2` from becoming activated even when `H11` is activated:
|
|
258
|
+
|
|
259
|
+
>>> ann.weights_hidden= [[[1000.0],
|
|
260
|
+
... [-1000.0]]]
|
|
261
|
+
|
|
262
|
+
To recapitulate, `H11` determines if at least one input is `True`, `H12` determines
|
|
263
|
+
if both inputs are `True`, and `H2` determines if precisely one input is `True`,
|
|
264
|
+
which is the solution for the XOR-problem:
|
|
265
|
+
|
|
266
|
+
>>> ann
|
|
267
|
+
ANN(
|
|
268
|
+
nmb_inputs=2,
|
|
269
|
+
nmb_neurons=(2, 1),
|
|
270
|
+
weights_input=[[1000.0, 500.0],
|
|
271
|
+
[1000.0, 500.0]],
|
|
272
|
+
weights_hidden=[[[1000.0],
|
|
273
|
+
[-1000.0]]],
|
|
274
|
+
weights_output=[[1.0]],
|
|
275
|
+
intercepts_hidden=[[-750.0, -750.0],
|
|
276
|
+
[-750.0, nan]],
|
|
277
|
+
intercepts_output=[0.0],
|
|
278
|
+
)
|
|
279
|
+
|
|
280
|
+
The following calculation confirms the proper configuration of our network:
|
|
281
|
+
|
|
282
|
+
>>> for inputs in ((0.0, 0.0),
|
|
283
|
+
... (1.0, 0.0),
|
|
284
|
+
... (0.0, 1.0),
|
|
285
|
+
... (1.0, 1.0)):
|
|
286
|
+
... ann.inputs = inputs
|
|
287
|
+
... ann.calculate_values()
|
|
288
|
+
... round_([inputs[0], inputs[1], ann.outputs[0]])
|
|
289
|
+
0.0, 0.0, 0.0
|
|
290
|
+
1.0, 0.0, 1.0
|
|
291
|
+
0.0, 1.0, 1.0
|
|
292
|
+
1.0, 1.0, 0.0
|
|
293
|
+
|
|
294
|
+
To elaborate on the last calculation, we show the corresponding activations of the
|
|
295
|
+
hidden neurons. As both inputs are `True`, both `H12` (upper left value) and `H22`
|
|
296
|
+
(upper right value) are activated, but `H2` (lower left value) is not:
|
|
297
|
+
|
|
298
|
+
>>> from hydpy import print_matrix
|
|
299
|
+
>>> print_matrix(ann.neurons)
|
|
300
|
+
| 1.0, 1.0 |
|
|
301
|
+
| 0.0, 0.0 |
|
|
302
|
+
|
|
303
|
+
Due to the sharp response function, the derivatives with respect to both inputs are
|
|
304
|
+
approximately zero:
|
|
305
|
+
|
|
306
|
+
>>> for inputs in ((0.0, 0.0),
|
|
307
|
+
... (1.0, 0.0),
|
|
308
|
+
... (0.0, 1.0),
|
|
309
|
+
... (1.0, 1.0)):
|
|
310
|
+
... ann.inputs = inputs
|
|
311
|
+
... ann.calculate_values()
|
|
312
|
+
... ann.calculate_derivatives(0)
|
|
313
|
+
... round_([inputs[0], inputs[1], ann.output_derivatives[0]])
|
|
314
|
+
0.0, 0.0, 0.0
|
|
315
|
+
1.0, 0.0, 0.0
|
|
316
|
+
0.0, 1.0, 0.0
|
|
317
|
+
1.0, 1.0, 0.0
|
|
318
|
+
|
|
319
|
+
To better validate the calculation of derivatives for multi-layer networks, we
|
|
320
|
+
decrease our network's weights (and, accordingly, the intercepts), making its
|
|
321
|
+
response more smooth:
|
|
322
|
+
|
|
323
|
+
>>> ann = ANN(nmb_inputs=2,
|
|
324
|
+
... nmb_neurons=(2, 1),
|
|
325
|
+
... nmb_outputs=1,
|
|
326
|
+
... weights_input=[[10.0, 5.0],
|
|
327
|
+
... [10.0, 5.0]],
|
|
328
|
+
... weights_hidden=[[[10.0],
|
|
329
|
+
... [-10.0]]],
|
|
330
|
+
... weights_output=[[1.0]],
|
|
331
|
+
... intercepts_hidden=[[-7.5, -7.5],
|
|
332
|
+
... [-7.5, nan]],
|
|
333
|
+
... intercepts_output=[0.0])
|
|
334
|
+
|
|
335
|
+
The results of method |ANN.calculate_derivatives| again agree with those of the
|
|
336
|
+
finite difference approximation:
|
|
337
|
+
|
|
338
|
+
>>> for inputs in ((0.0, 0.0),
|
|
339
|
+
... (1.0, 0.0),
|
|
340
|
+
... (0.0, 1.0),
|
|
341
|
+
... (1.0, 1.0)):
|
|
342
|
+
... ann.inputs = inputs
|
|
343
|
+
... ann.calculate_values()
|
|
344
|
+
... ann.calculate_derivatives(0)
|
|
345
|
+
... derivative1 = ann.output_derivatives[0]
|
|
346
|
+
... ann.calculate_derivatives(1)
|
|
347
|
+
... derivative2 = ann.output_derivatives[0]
|
|
348
|
+
... round_([inputs[0], inputs[1], derivative1, derivative2])
|
|
349
|
+
0.0, 0.0, 0.000015, 0.000015
|
|
350
|
+
1.0, 0.0, 0.694609, 0.694609
|
|
351
|
+
0.0, 1.0, 0.694609, 0.694609
|
|
352
|
+
1.0, 1.0, -0.004129, -0.004129
|
|
353
|
+
|
|
354
|
+
>>> d_input = 1e-8
|
|
355
|
+
>>> for inputs in ((0.0, 0.0),
|
|
356
|
+
... (1.0, 0.0),
|
|
357
|
+
... (0.0, 1.0),
|
|
358
|
+
... (1.0, 1.0)):
|
|
359
|
+
... derivatives = []
|
|
360
|
+
... for idx_input in range(2):
|
|
361
|
+
... ann.inputs = inputs
|
|
362
|
+
... ann.inputs[idx_input] = inputs[idx_input]-d_input/2.0
|
|
363
|
+
... ann.calculate_values()
|
|
364
|
+
... value0 = ann.outputs[0]
|
|
365
|
+
... ann.inputs[idx_input] = inputs[idx_input]+d_input/2.0
|
|
366
|
+
... ann.calculate_values()
|
|
367
|
+
... value1 = ann.outputs[0]
|
|
368
|
+
... derivatives.append((value1-value0)/d_input)
|
|
369
|
+
... round_([inputs[0], inputs[1]] + derivatives)
|
|
370
|
+
0.0, 0.0, 0.000015, 0.000015
|
|
371
|
+
1.0, 0.0, 0.694609, 0.694609
|
|
372
|
+
0.0, 1.0, 0.694609, 0.694609
|
|
373
|
+
1.0, 1.0, -0.004129, -0.004129
|
|
374
|
+
|
|
375
|
+
Note that Python class |ANN| handles a corresponding Cython extension class defined
|
|
376
|
+
in |annutils|, which does not protect itself against segmentation faults. But class
|
|
377
|
+
|ANN| takes up this task, meaning using its public members should always result in
|
|
378
|
+
readable exceptions instead of program crashes, e.g.:
|
|
379
|
+
|
|
380
|
+
>>> corrupted = ANN()
|
|
381
|
+
>>> del corrupted.nmb_outputs
|
|
382
|
+
>>> corrupted.nmb_outputs
|
|
383
|
+
Traceback (most recent call last):
|
|
384
|
+
...
|
|
385
|
+
hydpy.core.exceptiontools.AttributeNotReady: Attribute `nmb_outputs` of object \
|
|
386
|
+
`ann` has not been prepared so far.
|
|
387
|
+
|
|
388
|
+
>>> corrupted.outputs
|
|
389
|
+
Traceback (most recent call last):
|
|
390
|
+
...
|
|
391
|
+
hydpy.core.exceptiontools.AttributeNotReady: Attribute `outputs` of object `ann` \
|
|
392
|
+
is not usable so far. At least, you have to prepare attribute `nmb_outputs` first.
|
|
393
|
+
|
|
394
|
+
You can compare |ANN| objects for equality. The following exhaustive tests ensure
|
|
395
|
+
that one |ANN| is only considered equal with another |ANN| object with the same
|
|
396
|
+
network shape and parameter values:
|
|
397
|
+
|
|
398
|
+
>>> ann == ann
|
|
399
|
+
True
|
|
400
|
+
|
|
401
|
+
>>> ann == 1
|
|
402
|
+
False
|
|
403
|
+
|
|
404
|
+
>>> ann2 = ANN()
|
|
405
|
+
>>> ann2(nmb_inputs=2,
|
|
406
|
+
... nmb_neurons=(2, 1),
|
|
407
|
+
... nmb_outputs=1,
|
|
408
|
+
... weights_input=[[10.0, 5.0],
|
|
409
|
+
... [10.0, 5.0]],
|
|
410
|
+
... weights_hidden=[[[10.0],
|
|
411
|
+
... [-10.0]]],
|
|
412
|
+
... weights_output=[[1.0]],
|
|
413
|
+
... intercepts_hidden=[[-7.5, -7.5],
|
|
414
|
+
... [-7.5, nan]],
|
|
415
|
+
... intercepts_output=[0.0])
|
|
416
|
+
>>> ann == ann2
|
|
417
|
+
True
|
|
418
|
+
|
|
419
|
+
>>> ann2.weights_input[0, 0] = nan
|
|
420
|
+
>>> ann == ann2
|
|
421
|
+
False
|
|
422
|
+
>>> ann2.weights_input[0, 0] = 10.0
|
|
423
|
+
>>> ann == ann2
|
|
424
|
+
True
|
|
425
|
+
|
|
426
|
+
>>> ann2.weights_hidden[0, 1, 0] = 5.0
|
|
427
|
+
>>> ann == ann2
|
|
428
|
+
False
|
|
429
|
+
>>> ann2.weights_hidden[0, 1, 0] = -10.0
|
|
430
|
+
>>> ann == ann2
|
|
431
|
+
True
|
|
432
|
+
|
|
433
|
+
>>> ann2.weights_output[0, 0] = 2.0
|
|
434
|
+
>>> ann == ann2
|
|
435
|
+
False
|
|
436
|
+
>>> ann2.weights_output[0, 0] = 1.0
|
|
437
|
+
>>> ann == ann2
|
|
438
|
+
True
|
|
439
|
+
|
|
440
|
+
>>> ann2.intercepts_hidden[1, 0] = nan
|
|
441
|
+
>>> ann == ann2
|
|
442
|
+
False
|
|
443
|
+
>>> ann2.intercepts_hidden[1, 0] = -7.5
|
|
444
|
+
>>> ann == ann2
|
|
445
|
+
True
|
|
446
|
+
|
|
447
|
+
>>> ann2.intercepts_output[0] = 0.1
|
|
448
|
+
>>> ann == ann2
|
|
449
|
+
False
|
|
450
|
+
>>> ann2.intercepts_output[0] = 0.0
|
|
451
|
+
>>> ann == ann2
|
|
452
|
+
True
|
|
453
|
+
|
|
454
|
+
>>> ann2.activation[0, 0] = 0
|
|
455
|
+
>>> ann == ann2
|
|
456
|
+
False
|
|
457
|
+
>>> ann2.activation[0, 0] = 1
|
|
458
|
+
>>> ann == ann2
|
|
459
|
+
True
|
|
460
|
+
|
|
461
|
+
>>> ann2(nmb_inputs=1,
|
|
462
|
+
... nmb_neurons=(2, 1),
|
|
463
|
+
... nmb_outputs=1)
|
|
464
|
+
>>> ann == ann2
|
|
465
|
+
False
|
|
466
|
+
|
|
467
|
+
>>> ann2(nmb_inputs=2,
|
|
468
|
+
... nmb_neurons=(1, 1),
|
|
469
|
+
... nmb_outputs=1)
|
|
470
|
+
>>> ann == ann2
|
|
471
|
+
False
|
|
472
|
+
|
|
473
|
+
>>> ann2(nmb_inputs=2,
|
|
474
|
+
... nmb_neurons=(2, 1),
|
|
475
|
+
... nmb_outputs=2)
|
|
476
|
+
>>> ann == ann2
|
|
477
|
+
False
|
|
478
|
+
"""
|
|
479
|
+
|
|
480
|
+
_calgorithm: annutils.ANN
|
|
481
|
+
__max_nmb_neurons: int
|
|
482
|
+
|
|
483
|
+
def __init__(
|
|
484
|
+
self,
|
|
485
|
+
*,
|
|
486
|
+
nmb_inputs: int = 1,
|
|
487
|
+
nmb_neurons: tuple[int, ...] = (1,),
|
|
488
|
+
nmb_outputs: int = 1,
|
|
489
|
+
weights_input: MatrixInputFloat | None = None,
|
|
490
|
+
weights_output: MatrixInputFloat | None = None,
|
|
491
|
+
weights_hidden: TensorInputFloat | None = None,
|
|
492
|
+
intercepts_hidden: MatrixInputFloat | None = None,
|
|
493
|
+
intercepts_output: VectorInputFloat | None = None,
|
|
494
|
+
activation: MatrixInputInt | None = None,
|
|
495
|
+
) -> None:
|
|
496
|
+
self._calgorithm = annutils.ANN()
|
|
497
|
+
_ANNArrayProperty.add_cann(self, self._calgorithm)
|
|
498
|
+
self(
|
|
499
|
+
nmb_inputs=nmb_inputs,
|
|
500
|
+
nmb_neurons=nmb_neurons,
|
|
501
|
+
nmb_outputs=nmb_outputs,
|
|
502
|
+
weights_input=weights_input,
|
|
503
|
+
weights_output=weights_output,
|
|
504
|
+
weights_hidden=weights_hidden,
|
|
505
|
+
intercepts_hidden=intercepts_hidden,
|
|
506
|
+
intercepts_output=intercepts_output,
|
|
507
|
+
activation=activation,
|
|
508
|
+
)
|
|
509
|
+
|
|
510
|
+
def __call__(
|
|
511
|
+
self,
|
|
512
|
+
*,
|
|
513
|
+
nmb_inputs: int = 1,
|
|
514
|
+
nmb_neurons: tuple[int, ...] = (1,),
|
|
515
|
+
nmb_outputs: int = 1,
|
|
516
|
+
weights_input: MatrixInputFloat | None = None,
|
|
517
|
+
weights_output: MatrixInputFloat | None = None,
|
|
518
|
+
weights_hidden: TensorInputFloat | None = None,
|
|
519
|
+
intercepts_hidden: MatrixInputFloat | None = None,
|
|
520
|
+
intercepts_output: VectorInputFloat | None = None,
|
|
521
|
+
activation: MatrixInputInt | None = None,
|
|
522
|
+
) -> None:
|
|
523
|
+
self.nmb_inputs = nmb_inputs
|
|
524
|
+
self.nmb_outputs = nmb_outputs
|
|
525
|
+
self.nmb_neurons = nmb_neurons
|
|
526
|
+
self.weights_input = weights_input
|
|
527
|
+
self.weights_hidden = weights_hidden
|
|
528
|
+
self.weights_output = weights_output
|
|
529
|
+
self.intercepts_hidden = intercepts_hidden
|
|
530
|
+
self.intercepts_output = intercepts_output
|
|
531
|
+
self.activation = activation
|
|
532
|
+
del self.inputs
|
|
533
|
+
del self.outputs
|
|
534
|
+
del self.output_derivatives
|
|
535
|
+
del self.neurons
|
|
536
|
+
del self.neuron_derivatives
|
|
537
|
+
|
|
538
|
+
def __update_shapes(self) -> None:
|
|
539
|
+
if self.__protectedproperties.allready(self):
|
|
540
|
+
del self.weights_input
|
|
541
|
+
del self.weights_hidden
|
|
542
|
+
del self.weights_output
|
|
543
|
+
del self.intercepts_hidden
|
|
544
|
+
del self.intercepts_output
|
|
545
|
+
del self.activation
|
|
546
|
+
del self.inputs
|
|
547
|
+
del self.outputs
|
|
548
|
+
del self.output_derivatives
|
|
549
|
+
del self.neurons
|
|
550
|
+
del self.neuron_derivatives
|
|
551
|
+
|
|
552
|
+
def _get_nmb_inputs(self) -> int:
|
|
553
|
+
"""The number of input nodes.
|
|
554
|
+
|
|
555
|
+
>>> from hydpy import ANN
|
|
556
|
+
>>> ann = ANN(nmb_inputs=2, nmb_neurons=(2, 1), nmb_outputs=3)
|
|
557
|
+
>>> ann.nmb_inputs
|
|
558
|
+
2
|
|
559
|
+
>>> ann.nmb_inputs = 3
|
|
560
|
+
>>> ann.nmb_inputs
|
|
561
|
+
3
|
|
562
|
+
"""
|
|
563
|
+
return int(self._calgorithm.nmb_inputs)
|
|
564
|
+
|
|
565
|
+
def _set_nmb_inputs(self, value: int) -> None:
|
|
566
|
+
self._calgorithm.nmb_inputs = int(value)
|
|
567
|
+
self.__update_shapes()
|
|
568
|
+
|
|
569
|
+
def _del_nmb_inputs(self) -> None:
|
|
570
|
+
pass
|
|
571
|
+
|
|
572
|
+
nmb_inputs = propertytools.ProtectedProperty[int, int](
|
|
573
|
+
fget=_get_nmb_inputs, fset=_set_nmb_inputs, fdel=_del_nmb_inputs
|
|
574
|
+
)
|
|
575
|
+
|
|
576
|
+
def _get_nmb_outputs(self) -> int:
|
|
577
|
+
"""The number of output nodes.
|
|
578
|
+
|
|
579
|
+
>>> from hydpy import ANN
|
|
580
|
+
>>> ann = ANN(nmb_inputs=2, nmb_neurons=(2, 1), nmb_outputs=3)
|
|
581
|
+
>>> ann.nmb_outputs
|
|
582
|
+
3
|
|
583
|
+
>>> ann.nmb_outputs = 2
|
|
584
|
+
>>> ann.nmb_outputs
|
|
585
|
+
2
|
|
586
|
+
>>> del ann.nmb_outputs
|
|
587
|
+
>>> ann.nmb_outputs
|
|
588
|
+
Traceback (most recent call last):
|
|
589
|
+
...
|
|
590
|
+
hydpy.core.exceptiontools.AttributeNotReady: Attribute `nmb_outputs` of \
|
|
591
|
+
object `ann` has not been prepared so far.
|
|
592
|
+
"""
|
|
593
|
+
return int(self._calgorithm.nmb_outputs)
|
|
594
|
+
|
|
595
|
+
def _set_nmb_outputs(self, value: int) -> None:
|
|
596
|
+
self._calgorithm.nmb_outputs = int(value)
|
|
597
|
+
self.__update_shapes()
|
|
598
|
+
|
|
599
|
+
def _del_nmb_outputs(self) -> None:
|
|
600
|
+
pass
|
|
601
|
+
|
|
602
|
+
nmb_outputs = propertytools.ProtectedProperty[int, int](
|
|
603
|
+
fget=_get_nmb_outputs, fset=_set_nmb_outputs, fdel=_del_nmb_outputs
|
|
604
|
+
)
|
|
605
|
+
|
|
606
|
+
def _get_nmb_neurons(self) -> tuple[int, ...]:
|
|
607
|
+
"""The number of neurons of the hidden layers.
|
|
608
|
+
|
|
609
|
+
>>> from hydpy import ANN
|
|
610
|
+
>>> ann = ANN(nmb_inputs=2, nmb_neurons=(2, 1), nmb_outputs=3)
|
|
611
|
+
>>> ann.nmb_neurons
|
|
612
|
+
(2, 1)
|
|
613
|
+
>>> ann.nmb_neurons = (3,)
|
|
614
|
+
>>> ann.nmb_neurons
|
|
615
|
+
(3,)
|
|
616
|
+
>>> del ann.nmb_neurons
|
|
617
|
+
>>> ann.nmb_neurons
|
|
618
|
+
Traceback (most recent call last):
|
|
619
|
+
...
|
|
620
|
+
hydpy.core.exceptiontools.AttributeNotReady: Attribute `nmb_neurons` of \
|
|
621
|
+
object `ann` has not been prepared so far.
|
|
622
|
+
"""
|
|
623
|
+
return tuple(int(n) for n in self._calgorithm.nmb_neurons)
|
|
624
|
+
|
|
625
|
+
def _set_nmb_neurons(self, value: tuple[int, ...]) -> None:
|
|
626
|
+
self._calgorithm.nmb_neurons = numpy.array(value, dtype=config.NP_INT, ndmin=1)
|
|
627
|
+
self._calgorithm.nmb_layers = len(value)
|
|
628
|
+
self.__max_nmb_neurons = max(value)
|
|
629
|
+
self.__update_shapes()
|
|
630
|
+
|
|
631
|
+
def _del_nmb_neurons(self) -> None:
|
|
632
|
+
pass
|
|
633
|
+
|
|
634
|
+
nmb_neurons = propertytools.ProtectedProperty[tuple[int, ...], tuple[int, ...]](
|
|
635
|
+
fget=_get_nmb_neurons, fset=_set_nmb_neurons, fdel=_del_nmb_neurons
|
|
636
|
+
)
|
|
637
|
+
|
|
638
|
+
__protectedproperties = propertytools.ProtectedProperties(
|
|
639
|
+
nmb_inputs, nmb_outputs, nmb_neurons
|
|
640
|
+
)
|
|
641
|
+
|
|
642
|
+
@property
|
|
643
|
+
def nmb_weights_input(self) -> int:
|
|
644
|
+
"""The number of input weights.
|
|
645
|
+
|
|
646
|
+
>>> from hydpy import ANN
|
|
647
|
+
>>> ann = ANN(nmb_inputs=3, nmb_neurons=(2, 1), nmb_outputs=1)
|
|
648
|
+
>>> ann.nmb_weights_input
|
|
649
|
+
6
|
|
650
|
+
"""
|
|
651
|
+
return self.nmb_neurons[0] * self.nmb_inputs
|
|
652
|
+
|
|
653
|
+
@property
|
|
654
|
+
def shape_weights_input(self) -> tuple[int, int]:
|
|
655
|
+
"""The shape of the array containing the input weights.
|
|
656
|
+
|
|
657
|
+
The first integer value is the number of input nodes; the second integer value
|
|
658
|
+
is the number of neurons of the first hidden layer:
|
|
659
|
+
|
|
660
|
+
>>> from hydpy import ANN
|
|
661
|
+
>>> ann = ANN(nmb_inputs=3, nmb_neurons=(2, 1), nmb_outputs=1)
|
|
662
|
+
>>> ann.shape_weights_input
|
|
663
|
+
(3, 2)
|
|
664
|
+
"""
|
|
665
|
+
return self.nmb_inputs, self.nmb_neurons[0]
|
|
666
|
+
|
|
667
|
+
weights_input = _ANNArrayProperty[MatrixInputFloat | None, MatrixFloat](
|
|
668
|
+
protected=__protectedproperties,
|
|
669
|
+
doc="""The weights between all input nodes and neurons of the first hidden
|
|
670
|
+
layer.
|
|
671
|
+
|
|
672
|
+
All "weight properties" of class |ANN| are usable as explained in-depth for the
|
|
673
|
+
input weights below.
|
|
674
|
+
|
|
675
|
+
The input nodes and the neurons vary on the first and second axes of the
|
|
676
|
+
2-dimensional array, respectively (see property |ANN.shape_weights_input|):
|
|
677
|
+
|
|
678
|
+
>>> from hydpy import ANN, print_matrix
|
|
679
|
+
>>> ann = ANN(nmb_inputs=2, nmb_neurons=(3,))
|
|
680
|
+
>>> print_matrix(ann.weights_input)
|
|
681
|
+
| 0.0, 0.0, 0.0 |
|
|
682
|
+
| 0.0, 0.0, 0.0 |
|
|
683
|
+
|
|
684
|
+
The following error occurs when either the number of input nodes or of hidden
|
|
685
|
+
neurons is unknown:
|
|
686
|
+
|
|
687
|
+
>>> del ann.nmb_inputs
|
|
688
|
+
>>> ann.weights_input
|
|
689
|
+
Traceback (most recent call last):
|
|
690
|
+
...
|
|
691
|
+
hydpy.core.exceptiontools.AttributeNotReady: Attribute \
|
|
692
|
+
`weights_input` of object `ann` is not usable so far. At least, \
|
|
693
|
+
you have to prepare attribute `nmb_inputs` first.
|
|
694
|
+
>>> ann.nmb_inputs = 2
|
|
695
|
+
|
|
696
|
+
It is allowed to set values via slicing:
|
|
697
|
+
|
|
698
|
+
>>> ann.weights_input[:, 0] = 1.
|
|
699
|
+
>>> print_matrix(ann.weights_input)
|
|
700
|
+
| 1.0, 0.0, 0.0 |
|
|
701
|
+
| 1.0, 0.0, 0.0 |
|
|
702
|
+
|
|
703
|
+
If possible, property |ANN.weights_input| performs type conversions:
|
|
704
|
+
|
|
705
|
+
>>> ann.weights_input = "2"
|
|
706
|
+
>>> print_matrix(ann.weights_input)
|
|
707
|
+
| 2.0, 2.0, 2.0 |
|
|
708
|
+
| 2.0, 2.0, 2.0 |
|
|
709
|
+
|
|
710
|
+
One can assign whole matrices directly:
|
|
711
|
+
|
|
712
|
+
>>> import numpy
|
|
713
|
+
>>> ann.weights_input = numpy.eye(2, 3)
|
|
714
|
+
>>> print_matrix(ann.weights_input)
|
|
715
|
+
| 1.0, 0.0, 0.0 |
|
|
716
|
+
| 0.0, 1.0, 0.0 |
|
|
717
|
+
|
|
718
|
+
One can also delete the values contained in the array:
|
|
719
|
+
|
|
720
|
+
>>> del ann.weights_input
|
|
721
|
+
>>> print_matrix(ann.weights_input)
|
|
722
|
+
| 0.0, 0.0, 0.0 |
|
|
723
|
+
| 0.0, 0.0, 0.0 |
|
|
724
|
+
|
|
725
|
+
Errors like wrong shapes (or unconvertible inputs) result in error messages:
|
|
726
|
+
|
|
727
|
+
>>> ann.weights_input = numpy.eye(3)
|
|
728
|
+
Traceback (most recent call last):
|
|
729
|
+
...
|
|
730
|
+
ValueError: While trying to set the input weights of the artificial \
|
|
731
|
+
neural network `ann` of element `?`, the following error occurred: could not \
|
|
732
|
+
broadcast input array from shape (3,3) into shape (2,3)
|
|
733
|
+
""",
|
|
734
|
+
)
|
|
735
|
+
|
|
736
|
+
@property
|
|
737
|
+
def shape_weights_output(self) -> tuple[int, int]:
|
|
738
|
+
"""The shape of the array containing the output weights.
|
|
739
|
+
|
|
740
|
+
The first integer value is the number of neurons of the first hidden layer; the
|
|
741
|
+
second integer value is the number of output nodes:
|
|
742
|
+
|
|
743
|
+
>>> from hydpy import ANN
|
|
744
|
+
>>> ann = ANN(nmb_inputs=2, nmb_neurons=(2, 1), nmb_outputs=3)
|
|
745
|
+
>>> ann.shape_weights_output
|
|
746
|
+
(1, 3)
|
|
747
|
+
"""
|
|
748
|
+
return self.nmb_neurons[-1], self.nmb_outputs
|
|
749
|
+
|
|
750
|
+
@property
|
|
751
|
+
def nmb_weights_output(self) -> int:
|
|
752
|
+
"""The number of output weights.
|
|
753
|
+
|
|
754
|
+
>>> from hydpy import ANN
|
|
755
|
+
>>> ann = ANN(nmb_inputs=2, nmb_neurons=(2, 4), nmb_outputs=3)
|
|
756
|
+
>>> ann.nmb_weights_output
|
|
757
|
+
12
|
|
758
|
+
"""
|
|
759
|
+
return self.nmb_neurons[-1] * self.nmb_outputs
|
|
760
|
+
|
|
761
|
+
weights_output = _ANNArrayProperty[MatrixInputFloat | None, MatrixFloat](
|
|
762
|
+
protected=__protectedproperties,
|
|
763
|
+
doc="""The weights between all neurons of the last hidden layer and the output
|
|
764
|
+
nodes.
|
|
765
|
+
|
|
766
|
+
See the documentation on properties |ANN.shape_weights_output| and
|
|
767
|
+
|ANN.weights_input| for further information.
|
|
768
|
+
""",
|
|
769
|
+
)
|
|
770
|
+
|
|
771
|
+
@property
|
|
772
|
+
def shape_weights_hidden(self) -> tuple[int, int, int]:
|
|
773
|
+
"""The shape of the array containing the activation of the hidden neurons.
|
|
774
|
+
|
|
775
|
+
The first integer value is the number of connections between the hidden layers.
|
|
776
|
+
The second integer value is the maximum number of neurons of all hidden layers
|
|
777
|
+
feeding information into another hidden layer (all except the last one).
|
|
778
|
+
Finally, the third integer value is the maximum number of neurons of all hidden
|
|
779
|
+
layers receiving information from another hidden layer (all except the first
|
|
780
|
+
one):
|
|
781
|
+
|
|
782
|
+
>>> from hydpy import ANN
|
|
783
|
+
>>> ann = ANN(nmb_inputs=6, nmb_neurons=(4, 3, 2), nmb_outputs=6)
|
|
784
|
+
>>> ann.shape_weights_hidden
|
|
785
|
+
(2, 4, 3)
|
|
786
|
+
>>> ann(nmb_inputs=6, nmb_neurons=(4,), nmb_outputs=6)
|
|
787
|
+
>>> ann.shape_weights_hidden
|
|
788
|
+
(0, 0, 0)
|
|
789
|
+
"""
|
|
790
|
+
if self.nmb_layers > 1:
|
|
791
|
+
nmb_neurons = self.nmb_neurons
|
|
792
|
+
return self.nmb_layers - 1, max(nmb_neurons[:-1]), max(nmb_neurons[1:])
|
|
793
|
+
return 0, 0, 0
|
|
794
|
+
|
|
795
|
+
@property
|
|
796
|
+
def nmb_weights_hidden(self) -> int:
|
|
797
|
+
"""The number of hidden weights.
|
|
798
|
+
|
|
799
|
+
>>> from hydpy import ANN
|
|
800
|
+
>>> ann = ANN(nmb_inputs=2, nmb_neurons=(4, 3, 2), nmb_outputs=3)
|
|
801
|
+
>>> ann.nmb_weights_hidden
|
|
802
|
+
18
|
|
803
|
+
"""
|
|
804
|
+
nmb = 0
|
|
805
|
+
for idx_layer in range(self.nmb_layers - 1):
|
|
806
|
+
nmb += self.nmb_neurons[idx_layer] * self.nmb_neurons[idx_layer + 1]
|
|
807
|
+
return nmb
|
|
808
|
+
|
|
809
|
+
weights_hidden = _ANNArrayProperty[TensorInputFloat | None, TensorFloat](
|
|
810
|
+
protected=__protectedproperties,
|
|
811
|
+
doc="""The weights between the neurons of the different hidden layers.
|
|
812
|
+
|
|
813
|
+
See the documentation on properties |ANN.shape_weights_hidden| and
|
|
814
|
+
|ANN.weights_input| for further information.
|
|
815
|
+
""",
|
|
816
|
+
)
|
|
817
|
+
|
|
818
|
+
@property
|
|
819
|
+
def shape_intercepts_hidden(self) -> tuple[int, int]:
|
|
820
|
+
"""The shape of the array containing the intercepts of neurons of the hidden
|
|
821
|
+
layers.
|
|
822
|
+
|
|
823
|
+
The first integer value is the number of hidden layers; the second integer
|
|
824
|
+
value is the maximum number of neurons of all hidden layers:
|
|
825
|
+
|
|
826
|
+
>>> from hydpy import ANN
|
|
827
|
+
>>> ann = ANN(nmb_inputs=6, nmb_neurons=(4, 3, 2), nmb_outputs=6)
|
|
828
|
+
>>> ann.shape_intercepts_hidden
|
|
829
|
+
(3, 4)
|
|
830
|
+
"""
|
|
831
|
+
return self.nmb_layers, self.__max_nmb_neurons
|
|
832
|
+
|
|
833
|
+
@property
|
|
834
|
+
def nmb_intercepts_hidden(self) -> int:
|
|
835
|
+
"""The number of input intercepts."""
|
|
836
|
+
return sum(self.nmb_neurons)
|
|
837
|
+
|
|
838
|
+
intercepts_hidden = _ANNArrayProperty[MatrixInputFloat | None, MatrixFloat](
|
|
839
|
+
protected=__protectedproperties,
|
|
840
|
+
doc="""The intercepts of all neurons of the hidden layers.
|
|
841
|
+
|
|
842
|
+
See the documentation on properties |ANN.shape_intercepts_hidden| and
|
|
843
|
+
|ANN.weights_input| for further information.
|
|
844
|
+
""",
|
|
845
|
+
)
|
|
846
|
+
|
|
847
|
+
@property
|
|
848
|
+
def shape_intercepts_output(self) -> tuple[int]:
|
|
849
|
+
"""The shape of the array containing the intercepts of neurons of the hidden
|
|
850
|
+
layers.
|
|
851
|
+
|
|
852
|
+
The only integer value is the number of output nodes:
|
|
853
|
+
|
|
854
|
+
>>> from hydpy import ANN
|
|
855
|
+
>>> ann = ANN(nmb_inputs=2, nmb_neurons=(2, 1), nmb_outputs=3)
|
|
856
|
+
>>> ann.shape_intercepts_output
|
|
857
|
+
(3,)
|
|
858
|
+
"""
|
|
859
|
+
return (self.nmb_outputs,)
|
|
860
|
+
|
|
861
|
+
@property
|
|
862
|
+
def nmb_intercepts_output(self) -> int:
|
|
863
|
+
"""The number of output intercepts.
|
|
864
|
+
|
|
865
|
+
>>> from hydpy import ANN
|
|
866
|
+
>>> ann = ANN(nmb_inputs=2, nmb_neurons=(2, 1), nmb_outputs=3)
|
|
867
|
+
>>> ann.nmb_intercepts_output
|
|
868
|
+
3
|
|
869
|
+
"""
|
|
870
|
+
return self.nmb_outputs
|
|
871
|
+
|
|
872
|
+
intercepts_output = _ANNArrayProperty[VectorInputFloat | None, VectorFloat](
|
|
873
|
+
protected=__protectedproperties,
|
|
874
|
+
doc="""The intercepts of all output nodes.
|
|
875
|
+
|
|
876
|
+
See the documentation on properties |ANN.shape_intercepts_output| and
|
|
877
|
+
|ANN.weights_input| for further information.
|
|
878
|
+
""",
|
|
879
|
+
)
|
|
880
|
+
|
|
881
|
+
@property
|
|
882
|
+
def shape_activation(self) -> tuple[int, int]:
|
|
883
|
+
"""The shape of the array defining the activation function for each neuron of
|
|
884
|
+
the hidden layers.
|
|
885
|
+
|
|
886
|
+
The first integer value is the number of hidden layers; the second integer
|
|
887
|
+
value is the maximum number of neurons of all hidden layers:
|
|
888
|
+
|
|
889
|
+
>>> from hydpy import ANN
|
|
890
|
+
>>> ann = ANN(nmb_inputs=6, nmb_neurons=(4, 3, 2), nmb_outputs=6)
|
|
891
|
+
>>> ann.shape_activation
|
|
892
|
+
(3, 4)
|
|
893
|
+
"""
|
|
894
|
+
return self.nmb_layers, self.__max_nmb_neurons
|
|
895
|
+
|
|
896
|
+
activation = _ANNArrayProperty[MatrixInputInt | None, MatrixInt](
|
|
897
|
+
protected=__protectedproperties,
|
|
898
|
+
doc="""Indices for selecting suitable activation functions for the neurons of
|
|
899
|
+
the hidden layers.
|
|
900
|
+
|
|
901
|
+
By default, |ANN| uses the logistic function for calculating the activation of
|
|
902
|
+
the neurons of the hidden layers and uses the identity function for the output
|
|
903
|
+
nodes. However, property |ANN.activation| allows defining other activation
|
|
904
|
+
functions for the hidden neurons individually. So far, one can select the
|
|
905
|
+
identity function and a "filter version" of the logistic function as
|
|
906
|
+
alternatives -- others might follow.
|
|
907
|
+
|
|
908
|
+
Assume a neuron receives input :math:`i_1` and :math:`i_2` from two nodes of
|
|
909
|
+
the input layer or its upstream hidden layer. We wheight these input values as
|
|
910
|
+
usual:
|
|
911
|
+
|
|
912
|
+
:math:`x_1 = c + w_1 \\cdot i_1 + w_2 \\cdot i_2`
|
|
913
|
+
|
|
914
|
+
When selecting the identity function through setting the index value "0", the
|
|
915
|
+
activation of the considered neuron is:
|
|
916
|
+
|
|
917
|
+
:math:`a_1 = x_1`
|
|
918
|
+
|
|
919
|
+
Using the identity function is helpful for educational examples and for
|
|
920
|
+
bypassing input through one layer without introducing nonlinearity.
|
|
921
|
+
|
|
922
|
+
When selecting the logistic function through setting the index value "1", the
|
|
923
|
+
activation of the considered neuron is:
|
|
924
|
+
|
|
925
|
+
:math:`a_1 = 1-\\frac{1}{1+exp(x_1)}`
|
|
926
|
+
|
|
927
|
+
The logistic function is a standard function for constructing neural networks.
|
|
928
|
+
It allows to approximate any relationship within a specific range and accuracy,
|
|
929
|
+
provided the neural network is large enough.
|
|
930
|
+
|
|
931
|
+
When selecting the "filter version" of the logistic function through setting
|
|
932
|
+
the index value "2", the activation of the considered neuron is:
|
|
933
|
+
|
|
934
|
+
:math:`a_1 = 1-\\frac{1}{1+exp(x_1)} \\cdot i_1`
|
|
935
|
+
|
|
936
|
+
"Filter version" means that our neuron now filters the input of the single
|
|
937
|
+
input node placed at the corresponding position of its layer. This activation
|
|
938
|
+
function helps force the output of a neural network to be zero but never
|
|
939
|
+
negative beyond a certain threshold.
|
|
940
|
+
|
|
941
|
+
Like the main documentation on class |ANN|, we now define a relatively complex
|
|
942
|
+
network to show that the "normal" and the derivative calculations work. This
|
|
943
|
+
time, we set the activation function explicitly. "1" stands for the logistic
|
|
944
|
+
function, which we first use for all hidden neurons:
|
|
945
|
+
|
|
946
|
+
>>> from hydpy.auxs.anntools import ANN
|
|
947
|
+
>>> from hydpy import round_
|
|
948
|
+
>>> ann = ANN(nmb_inputs=2,
|
|
949
|
+
... nmb_neurons=(2, 2),
|
|
950
|
+
... nmb_outputs=2,
|
|
951
|
+
... weights_input=[[0.2, -0.1],
|
|
952
|
+
... [-1.7, 0.6]],
|
|
953
|
+
... weights_hidden=[[[-.5, 1.0],
|
|
954
|
+
... [0.4, 2.4]]],
|
|
955
|
+
... weights_output=[[0.8, -0.9],
|
|
956
|
+
... [0.5, -0.4]],
|
|
957
|
+
... intercepts_hidden=[[0.9, 0.0],
|
|
958
|
+
... [-0.4, -0.2]],
|
|
959
|
+
... intercepts_output=[1.3, -2.0],
|
|
960
|
+
... activation=[[1, 1],
|
|
961
|
+
... [1, 1]])
|
|
962
|
+
>>> ann.inputs = -0.1, 1.3
|
|
963
|
+
>>> ann.calculate_values()
|
|
964
|
+
>>> round_(ann.outputs)
|
|
965
|
+
2.074427, -2.734692
|
|
966
|
+
>>> for idx_input in range(2):
|
|
967
|
+
... ann.calculate_derivatives(idx_input)
|
|
968
|
+
... round_(ann.output_derivatives)
|
|
969
|
+
-0.006199, 0.006571
|
|
970
|
+
0.039804, -0.044169
|
|
971
|
+
|
|
972
|
+
In the next example, we want to apply the identity function for the second
|
|
973
|
+
neuron of the first hidden layer and the first neuron of the second hidden
|
|
974
|
+
layer. Therefore, we pass its index value "0" to the corresponding
|
|
975
|
+
|ANN.activation| entries:
|
|
976
|
+
|
|
977
|
+
>>> ann.activation = [[1, 0], [0, 1]]
|
|
978
|
+
>>> ann
|
|
979
|
+
ANN(
|
|
980
|
+
nmb_inputs=2,
|
|
981
|
+
nmb_neurons=(2, 2),
|
|
982
|
+
nmb_outputs=2,
|
|
983
|
+
weights_input=[[0.2, -0.1],
|
|
984
|
+
[-1.7, 0.6]],
|
|
985
|
+
weights_hidden=[[[-0.5, 1.0],
|
|
986
|
+
[0.4, 2.4]]],
|
|
987
|
+
weights_output=[[0.8, -0.9],
|
|
988
|
+
[0.5, -0.4]],
|
|
989
|
+
intercepts_hidden=[[0.9, 0.0],
|
|
990
|
+
[-0.4, -0.2]],
|
|
991
|
+
intercepts_output=[1.3, -2.0],
|
|
992
|
+
activation=[[1, 0],
|
|
993
|
+
[0, 1]],
|
|
994
|
+
)
|
|
995
|
+
|
|
996
|
+
The agreement between the analytical and the numerical derivatives gives us
|
|
997
|
+
confidence everything works fine:
|
|
998
|
+
|
|
999
|
+
>>> ann.calculate_values()
|
|
1000
|
+
>>> round_(ann.outputs)
|
|
1001
|
+
1.584373, -2.178468
|
|
1002
|
+
>>> for idx_input in range(2):
|
|
1003
|
+
... ann.calculate_derivatives(idx_input)
|
|
1004
|
+
... round_(ann.output_derivatives)
|
|
1005
|
+
-0.056898, 0.060219
|
|
1006
|
+
0.369807, -0.394801
|
|
1007
|
+
>>> d_input = 1e-8
|
|
1008
|
+
>>> for idx_input in range(2):
|
|
1009
|
+
... input_ = ann.inputs[idx_input]
|
|
1010
|
+
... ann.inputs[idx_input] = input_-d_input/2.0
|
|
1011
|
+
... ann.calculate_values()
|
|
1012
|
+
... values0 = ann.outputs.copy()
|
|
1013
|
+
... ann.inputs[idx_input] = input_+d_input/2.0
|
|
1014
|
+
... ann.calculate_values()
|
|
1015
|
+
... values1 = ann.outputs.copy()
|
|
1016
|
+
... ann.inputs[idx_input] = input_
|
|
1017
|
+
... round_((values1-values0)/d_input)
|
|
1018
|
+
-0.056898, 0.060219
|
|
1019
|
+
0.369807, -0.394801
|
|
1020
|
+
|
|
1021
|
+
Finally, we perform the same check for the "filter version" of the logistic
|
|
1022
|
+
function:
|
|
1023
|
+
|
|
1024
|
+
>>> ann.activation = [[1, 2], [2, 1]]
|
|
1025
|
+
>>> ann.calculate_values()
|
|
1026
|
+
>>> round_(ann.outputs)
|
|
1027
|
+
1.825606, -2.445682
|
|
1028
|
+
>>> for idx_input in range(2):
|
|
1029
|
+
... ann.calculate_derivatives(idx_input)
|
|
1030
|
+
... round_(ann.output_derivatives)
|
|
1031
|
+
0.009532, -0.011236
|
|
1032
|
+
-0.001715, 0.02872
|
|
1033
|
+
>>> d_input = 1e-8
|
|
1034
|
+
>>> for idx_input in range(2):
|
|
1035
|
+
... input_ = ann.inputs[idx_input]
|
|
1036
|
+
... ann.inputs[idx_input] = input_-d_input/2.0
|
|
1037
|
+
... ann.calculate_values()
|
|
1038
|
+
... values0 = ann.outputs.copy()
|
|
1039
|
+
... ann.inputs[idx_input] = input_+d_input/2.0
|
|
1040
|
+
... ann.calculate_values()
|
|
1041
|
+
... values1 = ann.outputs.copy()
|
|
1042
|
+
... ann.inputs[idx_input] = input_
|
|
1043
|
+
... round_((values1-values0)/d_input)
|
|
1044
|
+
0.009532, -0.011236
|
|
1045
|
+
-0.001715, 0.02872
|
|
1046
|
+
""",
|
|
1047
|
+
)
|
|
1048
|
+
|
|
1049
|
+
@property
|
|
1050
|
+
def shape_inputs(self) -> tuple[int]:
|
|
1051
|
+
"""The shape of the array containing the input values.
|
|
1052
|
+
|
|
1053
|
+
The only integer value is the number of input nodes:
|
|
1054
|
+
|
|
1055
|
+
>>> from hydpy import ANN
|
|
1056
|
+
>>> ann = ANN(nmb_inputs=5, nmb_neurons=(2, 1), nmb_outputs=2)
|
|
1057
|
+
>>> ann.shape_inputs
|
|
1058
|
+
(5,)
|
|
1059
|
+
"""
|
|
1060
|
+
return (self.nmb_inputs,)
|
|
1061
|
+
|
|
1062
|
+
inputs = _ANNArrayProperty[VectorInputFloat | None, VectorFloat](
|
|
1063
|
+
protected=__protectedproperties,
|
|
1064
|
+
doc="""The values of the input nodes.
|
|
1065
|
+
|
|
1066
|
+
See the documentation on properties |ANN.shape_inputs| and |ANN.weights_input|
|
|
1067
|
+
for further information.
|
|
1068
|
+
""",
|
|
1069
|
+
)
|
|
1070
|
+
|
|
1071
|
+
@property
|
|
1072
|
+
def shape_outputs(self) -> tuple[int]:
|
|
1073
|
+
"""The shape of the array containing the output values.
|
|
1074
|
+
|
|
1075
|
+
The only integer value is the number of output nodes:
|
|
1076
|
+
|
|
1077
|
+
>>> from hydpy import ANN
|
|
1078
|
+
>>> ann = ANN(nmb_inputs=2, nmb_neurons=(2, 1), nmb_outputs=6)
|
|
1079
|
+
>>> ann.shape_outputs
|
|
1080
|
+
(6,)
|
|
1081
|
+
"""
|
|
1082
|
+
return (self.nmb_outputs,)
|
|
1083
|
+
|
|
1084
|
+
outputs = _ANNArrayProperty[VectorInputFloat | None, VectorFloat](
|
|
1085
|
+
protected=__protectedproperties,
|
|
1086
|
+
doc="""The values of the output nodes.
|
|
1087
|
+
|
|
1088
|
+
See the documentation on properties |ANN.shape_outputs| and |ANN.weights_input|
|
|
1089
|
+
for further information.
|
|
1090
|
+
""",
|
|
1091
|
+
)
|
|
1092
|
+
|
|
1093
|
+
@property
|
|
1094
|
+
def shape_output_derivatives(self) -> tuple[int]:
|
|
1095
|
+
"""The shape of the array containing the output derivatives.
|
|
1096
|
+
|
|
1097
|
+
The only integer value is the number of output nodes:
|
|
1098
|
+
|
|
1099
|
+
>>> from hydpy import ANN
|
|
1100
|
+
>>> ann = ANN(nmb_inputs=2, nmb_neurons=(2, 1), nmb_outputs=6)
|
|
1101
|
+
>>> ann.shape_output_derivatives
|
|
1102
|
+
(6,)
|
|
1103
|
+
"""
|
|
1104
|
+
return (self.nmb_outputs,)
|
|
1105
|
+
|
|
1106
|
+
output_derivatives = _ANNArrayProperty[VectorInputFloat | None, VectorFloat](
|
|
1107
|
+
protected=__protectedproperties,
|
|
1108
|
+
doc="""The derivatives of the output nodes.
|
|
1109
|
+
|
|
1110
|
+
See the documentation on properties |ANN.shape_output_derivatives| and
|
|
1111
|
+
|ANN.weights_input| for further information.
|
|
1112
|
+
""",
|
|
1113
|
+
)
|
|
1114
|
+
|
|
1115
|
+
def _get_nmb_layers(self) -> int:
|
|
1116
|
+
"""The number of hidden layers.
|
|
1117
|
+
|
|
1118
|
+
>>> from hydpy import ANN
|
|
1119
|
+
>>> ann = ANN(nmb_inputs=2, nmb_neurons=(2, 1), nmb_outputs=3)
|
|
1120
|
+
>>> ann.nmb_layers
|
|
1121
|
+
2
|
|
1122
|
+
"""
|
|
1123
|
+
return self._calgorithm.nmb_layers
|
|
1124
|
+
|
|
1125
|
+
nmb_layers = propertytools.DependentProperty[int, int](
|
|
1126
|
+
protected=__protectedproperties, fget=_get_nmb_layers
|
|
1127
|
+
)
|
|
1128
|
+
|
|
1129
|
+
def _get_shape_neurons(self) -> tuple[int, int]:
|
|
1130
|
+
"""The shape of the array containing the activations of the neurons of the
|
|
1131
|
+
hidden layers.
|
|
1132
|
+
|
|
1133
|
+
The first integer value is the number of hidden layers; the second integer
|
|
1134
|
+
value is the maximum number of neurons of all hidden layers:
|
|
1135
|
+
|
|
1136
|
+
>>> from hydpy import ANN
|
|
1137
|
+
>>> ann = ANN(nmb_inputs=2, nmb_neurons=(4, 3, 2), nmb_outputs=6)
|
|
1138
|
+
>>> ann.shape_neurons
|
|
1139
|
+
(3, 4)
|
|
1140
|
+
"""
|
|
1141
|
+
return self.nmb_layers, self.__max_nmb_neurons
|
|
1142
|
+
|
|
1143
|
+
shape_neurons = propertytools.DependentProperty[tuple[int, int], tuple[int, int]](
|
|
1144
|
+
protected=__protectedproperties, fget=_get_shape_neurons
|
|
1145
|
+
)
|
|
1146
|
+
|
|
1147
|
+
neurons = _ANNArrayProperty[MatrixInputFloat | None, MatrixFloat](
|
|
1148
|
+
protected=__protectedproperties,
|
|
1149
|
+
doc="""The activation of the neurons of the hidden layers.
|
|
1150
|
+
|
|
1151
|
+
See the documentation on properties |ANN.shape_neurons| and |ANN.weights_input|
|
|
1152
|
+
for further information.
|
|
1153
|
+
""",
|
|
1154
|
+
)
|
|
1155
|
+
|
|
1156
|
+
def _get_shape_neuron_derivatives(self) -> tuple[int, int]:
|
|
1157
|
+
"""The shape of the array containing the derivatives of the activities of the
|
|
1158
|
+
neurons of the hidden layers.
|
|
1159
|
+
|
|
1160
|
+
The first integer value is the number of hidden layers; the second integer
|
|
1161
|
+
value is the maximum number of neurons of all hidden layers:
|
|
1162
|
+
|
|
1163
|
+
>>> from hydpy import ANN
|
|
1164
|
+
>>> ann = ANN(nmb_inputs=2, nmb_neurons=(4, 3, 2), nmb_outputs=6)
|
|
1165
|
+
>>> ann.shape_neuron_derivatives
|
|
1166
|
+
(3, 4)
|
|
1167
|
+
"""
|
|
1168
|
+
return self.nmb_layers, self.__max_nmb_neurons
|
|
1169
|
+
|
|
1170
|
+
shape_neuron_derivatives = propertytools.DependentProperty[
|
|
1171
|
+
tuple[int, int], tuple[int, int]
|
|
1172
|
+
](protected=__protectedproperties, fget=_get_shape_neuron_derivatives)
|
|
1173
|
+
|
|
1174
|
+
neuron_derivatives = _ANNArrayProperty[MatrixInputFloat | None, MatrixFloat](
|
|
1175
|
+
protected=__protectedproperties,
|
|
1176
|
+
doc="""The derivatives of the activation of the neurons of the hidden layers.
|
|
1177
|
+
|
|
1178
|
+
See the documentation on properties |ANN.shape_neuron_derivatives| and
|
|
1179
|
+
|ANN.weights_input| for further information.
|
|
1180
|
+
""",
|
|
1181
|
+
)
|
|
1182
|
+
|
|
1183
|
+
def calculate_values(self) -> None:
|
|
1184
|
+
"""Calculate the network output values based on the input values defined
|
|
1185
|
+
previously.
|
|
1186
|
+
|
|
1187
|
+
For more information, see the documentation on class |ANN|.
|
|
1188
|
+
"""
|
|
1189
|
+
self._calgorithm.calculate_values()
|
|
1190
|
+
|
|
1191
|
+
def calculate_derivatives(self, idx: int, /) -> None:
|
|
1192
|
+
"""Calculate the derivatives of the network output values with respect to the
|
|
1193
|
+
input value of the given index.
|
|
1194
|
+
|
|
1195
|
+
For more information, see the documentation on class |ANN|.
|
|
1196
|
+
"""
|
|
1197
|
+
self._calgorithm.calculate_derivatives(idx)
|
|
1198
|
+
|
|
1199
|
+
@property
|
|
1200
|
+
def nmb_weights(self) -> int:
|
|
1201
|
+
"""The number of all input, inner, and output weights.
|
|
1202
|
+
|
|
1203
|
+
>>> from hydpy import ANN
|
|
1204
|
+
>>> ann = ANN(nmb_inputs=1, nmb_neurons=(2, 3), nmb_outputs=4)
|
|
1205
|
+
>>> ann.nmb_weights
|
|
1206
|
+
20
|
|
1207
|
+
"""
|
|
1208
|
+
return (
|
|
1209
|
+
self.nmb_weights_input + self.nmb_weights_hidden + self.nmb_weights_output
|
|
1210
|
+
)
|
|
1211
|
+
|
|
1212
|
+
@property
|
|
1213
|
+
def nmb_intercepts(self) -> int:
|
|
1214
|
+
"""The number of all inner and output intercepts.
|
|
1215
|
+
|
|
1216
|
+
>>> from hydpy import ANN
|
|
1217
|
+
>>> ann = ANN(nmb_inputs=1, nmb_neurons=(2, 3), nmb_outputs=4)
|
|
1218
|
+
>>> ann.nmb_intercepts
|
|
1219
|
+
9
|
|
1220
|
+
"""
|
|
1221
|
+
return self.nmb_intercepts_hidden + self.nmb_intercepts_output
|
|
1222
|
+
|
|
1223
|
+
@property
|
|
1224
|
+
def nmb_parameters(self) -> int:
|
|
1225
|
+
"""The sum of |ANN.nmb_weights| and |ANN.nmb_intercepts|.
|
|
1226
|
+
|
|
1227
|
+
>>> from hydpy import ANN
|
|
1228
|
+
>>> ann = ANN(nmb_inputs=1, nmb_neurons=(2, 3), nmb_outputs=4)
|
|
1229
|
+
>>> ann.nmb_parameters
|
|
1230
|
+
29
|
|
1231
|
+
"""
|
|
1232
|
+
return self.nmb_weights + self.nmb_intercepts
|
|
1233
|
+
|
|
1234
|
+
def verify(self) -> None:
|
|
1235
|
+
"""Raise a |RuntimeError| if the network's shape is not defined completely.
|
|
1236
|
+
|
|
1237
|
+
>>> from hydpy import ANN
|
|
1238
|
+
>>> ann = ANN()
|
|
1239
|
+
>>> del ann.nmb_inputs
|
|
1240
|
+
>>> ann.verify()
|
|
1241
|
+
Traceback (most recent call last):
|
|
1242
|
+
...
|
|
1243
|
+
RuntimeError: The shape of the the artificial neural network parameter `ann` \
|
|
1244
|
+
of element `?` is not properly defined.
|
|
1245
|
+
"""
|
|
1246
|
+
if not self.__protectedproperties.allready(self):
|
|
1247
|
+
raise RuntimeError(
|
|
1248
|
+
f"The shape of the the artificial neural network parameter "
|
|
1249
|
+
f"{objecttools.elementphrase(self)} is not properly defined."
|
|
1250
|
+
)
|
|
1251
|
+
|
|
1252
|
+
def assignrepr(self, prefix: str, indent: int = 0) -> str:
|
|
1253
|
+
"""Return a string representation of the actual |ANN| object prefixed with the
|
|
1254
|
+
given string."""
|
|
1255
|
+
l = objecttools.assignrepr_list
|
|
1256
|
+
l2 = objecttools.assignrepr_list2
|
|
1257
|
+
l3 = objecttools.assignrepr_list3
|
|
1258
|
+
blanks = (indent + 4) * " "
|
|
1259
|
+
lines = [f"{prefix}{type(self).__name__}("]
|
|
1260
|
+
if self.nmb_inputs != 1:
|
|
1261
|
+
lines.append(f"{blanks}nmb_inputs={self.nmb_inputs},")
|
|
1262
|
+
if self.nmb_neurons != (1,):
|
|
1263
|
+
lines.append(f"{blanks}nmb_neurons={self.nmb_neurons},")
|
|
1264
|
+
if self.nmb_outputs != 1:
|
|
1265
|
+
lines.append(f"{blanks}nmb_outputs={self.nmb_outputs},")
|
|
1266
|
+
lines.append(l2(self.weights_input, f"{blanks}weights_input=") + ",")
|
|
1267
|
+
if self.nmb_layers > 1:
|
|
1268
|
+
lines.append(l3(self.weights_hidden, f"{blanks}weights_hidden=") + ",")
|
|
1269
|
+
lines.append(l2(self.weights_output, f"{blanks}weights_output=") + ",")
|
|
1270
|
+
lines.append(l2(self.intercepts_hidden, f"{blanks}intercepts_hidden=") + ",")
|
|
1271
|
+
lines.append(l(self.intercepts_output, f"{blanks}intercepts_output=") + ",")
|
|
1272
|
+
if numpy.any(self.activation != 1):
|
|
1273
|
+
lines.append(l2(self.activation, f"{blanks}activation=") + ",")
|
|
1274
|
+
lines.append(f'{indent*" "})')
|
|
1275
|
+
return "\n".join(lines)
|
|
1276
|
+
|
|
1277
|
+
def __repr__(self) -> str:
|
|
1278
|
+
return self.assignrepr(prefix="")
|
|
1279
|
+
|
|
1280
|
+
def __hash__(self) -> int:
|
|
1281
|
+
return id(self)
|
|
1282
|
+
|
|
1283
|
+
def __eq__(self, other: object) -> bool:
|
|
1284
|
+
def _equal_array(
|
|
1285
|
+
x: VectorFloat | MatrixInt | MatrixFloat,
|
|
1286
|
+
y: VectorFloat | MatrixInt | MatrixFloat,
|
|
1287
|
+
) -> bool:
|
|
1288
|
+
idxs = ~(numpy.isnan(x) * numpy.isnan(y))
|
|
1289
|
+
return bool(numpy.all(x[idxs] == y[idxs]))
|
|
1290
|
+
|
|
1291
|
+
if id(self) == id(other):
|
|
1292
|
+
return True
|
|
1293
|
+
if isinstance(other, ANN):
|
|
1294
|
+
return (
|
|
1295
|
+
self.shape_inputs == other.shape_inputs
|
|
1296
|
+
and self.shape_neurons == other.shape_neurons
|
|
1297
|
+
and self.shape_outputs == other.shape_outputs
|
|
1298
|
+
and _equal_array(self.weights_input[:], other.weights_input[:])
|
|
1299
|
+
and _equal_array(self.weights_hidden, other.weights_hidden)
|
|
1300
|
+
and _equal_array(self.weights_output, other.weights_output)
|
|
1301
|
+
and _equal_array(self.intercepts_hidden, other.intercepts_hidden)
|
|
1302
|
+
and _equal_array(self.intercepts_output, other.intercepts_output)
|
|
1303
|
+
and _equal_array(self.activation, other.activation)
|
|
1304
|
+
)
|
|
1305
|
+
return NotImplemented
|