text:
function pl_pvcam_get_ver(pvcam_version::Ref{uns16})
    ccall((:pl_pvcam_get_ver, :libpvcam), rs_bool, (Ref{uns16},), pvcam_version)
end

function pl_pvcam_init()
    ccall((:pl_pvcam_init, :libpvcam), rs_bool, ())
end

function pl_pvcam_uninit()
    ccall((:pl_pvcam_uninit, :libpvcam), rs_bool, ())
end

function pl_cam_check(hcam::int16)
    ccall((:pl_cam_check, :libpvcam), rs_bool, (int16,), hcam)
end

function pl_cam_close(hcam::int16)
    ccall((:pl_cam_close, :libpvcam), rs_bool, (int16,), hcam)
end

function pl_cam_get_name(cam_num::int16, camera_name)
    ccall((:pl_cam_get_name, :libpvcam), rs_bool, (int16, Cstring), cam_num, camera_name)
end

function pl_cam_get_total(totl_cams::Ref{int16})
    ccall((:pl_cam_get_total, :libpvcam), rs_bool, (Ref{int16},), totl_cams)
end

function pl_cam_open(camera_name, hcam::Ref{int16}, o_mode::int16)
    ccall((:pl_cam_open, :libpvcam), rs_bool, (Cstring, Ref{int16}, int16), camera_name, hcam, o_mode)
end

function pl_cam_register_callback(hcam::int16, callback_event::int32, callback::Ref{Cvoid})
    ccall((:pl_cam_register_callback, :libpvcam), rs_bool, (int16, int32, Ref{Cvoid}), hcam, callback_event, callback)
end

function pl_cam_register_callback_ex(hcam::int16, callback_event::int32, callback::Ref{Cvoid}, context::Ref{Cvoid})
    ccall((:pl_cam_register_callback_ex, :libpvcam), rs_bool, (int16, int32, Ref{Cvoid}, Ref{Cvoid}), hcam, callback_event, callback, context)
end

function pl_cam_register_callback_ex2(hcam::int16, callback_event::int32, callback::Ref{Cvoid})
    ccall((:pl_cam_register_callback_ex2, :libpvcam), rs_bool, (int16, int32, Ref{Cvoid}), hcam, callback_event, callback)
end

function pl_cam_register_callback_ex3(hcam::int16, callback_event::int32, callback::Ref{Cvoid}, context::Ref{Cvoid})
    ccall((:pl_cam_register_callback_ex3, :libpvcam), rs_bool, (int16, int32, Ref{Cvoid}, Ref{Cvoid}), hcam, callback_event, callback, context)
end

function pl_cam_deregister_callback(hcam::int16, callback_event::int32)
    ccall((:pl_cam_deregister_callback, :libpvcam), rs_bool, (int16, int32), hcam, callback_event)
end

function pl_error_code()
    ccall((:pl_error_code, :libpvcam), int16, ())
end

function pl_error_message(err_code::int16, msg)
    ccall((:pl_error_message, :libpvcam), rs_bool, (int16, Cstring), err_code, msg)
end

function pl_get_param(hcam::int16, param_id::uns32, param_attribute::int16, param_value::Ref{Cvoid})
    ccall((:pl_get_param, :libpvcam), rs_bool, (int16, uns32, int16, Ref{Cvoid}), hcam, param_id, param_attribute, param_value)
end

function pl_set_param(hcam::int16, param_id::uns32, param_value::Ref{Cvoid})
    ccall((:pl_set_param, :libpvcam), rs_bool, (int16, uns32, Ref{Cvoid}), hcam, param_id, param_value)
end

function pl_get_enum_param(hcam::int16, param_id::uns32, index::uns32, value::Ref{int32}, desc, length::uns32)
    ccall((:pl_get_enum_param, :libpvcam), rs_bool, (int16, uns32, uns32, Ref{int32}, Cstring, uns32), hcam, param_id, index, value, desc, length)
end

function pl_enum_str_length(hcam::int16, param_id::uns32, index::uns32, length::Ref{uns32})
    ccall((:pl_enum_str_length, :libpvcam), rs_bool, (int16, uns32, uns32, Ref{uns32}), hcam, param_id, index, length)
end

function pl_pp_reset(hcam::int16)
    ccall((:pl_pp_reset, :libpvcam), rs_bool, (int16,), hcam)
end

function pl_create_smart_stream_struct(array::Ref{Ptr{smart_stream_type}}, entries::uns16)
    ccall((:pl_create_smart_stream_struct, :libpvcam), rs_bool, (Ref{Ptr{smart_stream_type}}, uns16), array, entries)
end

function pl_release_smart_stream_struct(array::Ref{Ptr{smart_stream_type}})
    ccall((:pl_release_smart_stream_struct, :libpvcam), rs_bool, (Ref{Ptr{smart_stream_type}},), array)
end

function pl_create_frame_info_struct(new_frame::Ref{Ptr{FRAME_INFO}})
    ccall((:pl_create_frame_info_struct, :libpvcam), rs_bool, (Ref{Ptr{FRAME_INFO}},), new_frame)
end

function pl_release_frame_info_struct(frame_to_delete::Ref{FRAME_INFO})
    ccall((:pl_release_frame_info_struct, :libpvcam), rs_bool, (Ref{FRAME_INFO},), frame_to_delete)
end

function pl_exp_setup_seq(hcam::int16, exp_total::uns16, rgn_total::uns16, rgn_array::Ref{rgn_type}, exp_mode::int16, exposure_time::uns32, exp_bytes::Ref{uns32})
    ccall((:pl_exp_setup_seq, :libpvcam), rs_bool, (int16, uns16, uns16, Ref{rgn_type}, int16, uns32, Ref{uns32}), hcam, exp_total, rgn_total, rgn_array, exp_mode, exposure_time, exp_bytes)
end

function pl_exp_start_seq(hcam::int16, pixel_stream::Ref{Cvoid})
    ccall((:pl_exp_start_seq, :libpvcam), rs_bool, (int16, Ref{Cvoid}), hcam, pixel_stream)
end

function pl_exp_setup_cont(hcam::int16, rgn_total::uns16, rgn_array::Ref{rgn_type}, exp_mode::int16, exposure_time::uns32, exp_bytes::Ref{uns32}, buffer_mode::int16)
    ccall((:pl_exp_setup_cont, :libpvcam), rs_bool, (int16, uns16, Ref{rgn_type}, int16, uns32, Ref{uns32}, int16), hcam, rgn_total, rgn_array, exp_mode, exposure_time, exp_bytes, buffer_mode)
end

function pl_exp_start_cont(hcam::int16, pixel_stream::Ref{Cvoid}, size::uns32)
    ccall((:pl_exp_start_cont, :libpvcam), rs_bool, (int16, Ref{Cvoid}, uns32), hcam, pixel_stream, size)
end

function pl_exp_check_status(hcam::int16, status::Ref{int16}, bytes_arrived::Ref{uns32})
    ccall((:pl_exp_check_status, :libpvcam), rs_bool, (int16, Ref{int16}, Ref{uns32}), hcam, status, bytes_arrived)
end

function pl_exp_check_cont_status(hcam::int16, status::Ref{int16}, bytes_arrived::Ref{uns32}, buffer_cnt::Ref{uns32})
    ccall((:pl_exp_check_cont_status, :libpvcam), rs_bool, (int16, Ref{int16}, Ref{uns32}, Ref{uns32}), hcam, status, bytes_arrived, buffer_cnt)
end

function pl_exp_check_cont_status_ex(hcam::int16, status::Ref{int16}, byte_cnt::Ref{uns32}, buffer_cnt::Ref{uns32}, frame_info::Ref{FRAME_INFO})
    ccall((:pl_exp_check_cont_status_ex, :libpvcam), rs_bool, (int16, Ref{int16}, Ref{uns32}, Ref{uns32}, Ref{FRAME_INFO}), hcam, status, byte_cnt, buffer_cnt, frame_info)
end

function pl_exp_get_latest_frame(hcam::int16, frame::Ref{Ptr{Cvoid}})
    ccall((:pl_exp_get_latest_frame, :libpvcam), rs_bool, (int16, Ref{Ptr{Cvoid}}), hcam, frame)
end

function pl_exp_get_latest_frame_ex(hcam::int16, frame::Ref{Ptr{Cvoid}}, frame_info::Ref{FRAME_INFO})
    ccall((:pl_exp_get_latest_frame_ex, :libpvcam), rs_bool, (int16, Ref{Ptr{Cvoid}}, Ref{FRAME_INFO}), hcam, frame, frame_info)
end

function pl_exp_get_oldest_frame(hcam::int16, frame::Ref{Ptr{Cvoid}})
    ccall((:pl_exp_get_oldest_frame, :libpvcam), rs_bool, (int16, Ref{Ptr{Cvoid}}), hcam, frame)
end

function pl_exp_get_oldest_frame_ex(hcam::int16, frame::Ref{Ptr{Cvoid}}, frame_info::Ref{FRAME_INFO})
    ccall((:pl_exp_get_oldest_frame_ex, :libpvcam), rs_bool, (int16, Ref{Ptr{Cvoid}}, Ref{FRAME_INFO}), hcam, frame, frame_info)
end

function pl_exp_unlock_oldest_frame(hcam::int16)
    ccall((:pl_exp_unlock_oldest_frame, :libpvcam), rs_bool, (int16,), hcam)
end

function pl_exp_stop_cont(hcam::int16, cam_state::int16)
    ccall((:pl_exp_stop_cont, :libpvcam), rs_bool, (int16, int16), hcam, cam_state)
end

function pl_exp_abort(hcam::int16, cam_state::int16)
    ccall((:pl_exp_abort, :libpvcam), rs_bool, (int16, int16), hcam, cam_state)
end

function pl_exp_finish_seq(hcam::int16, pixel_stream::Ref{Cvoid}, hbuf::int16)
    ccall((:pl_exp_finish_seq, :libpvcam), rs_bool, (int16, Ref{Cvoid}, int16), hcam, pixel_stream, hbuf)
end

function pl_io_script_control(hcam::int16, addr::uns16, state::flt64, location::uns32)
    ccall((:pl_io_script_control, :libpvcam), rs_bool, (int16, uns16, flt64, uns32), hcam, addr, state, location)
end

function pl_io_clear_script_control(hcam::int16)
    ccall((:pl_io_clear_script_control, :libpvcam), rs_bool, (int16,), hcam)
end

function pl_exp_init_seq()
    ccall((:pl_exp_init_seq, :libpvcam), rs_bool, ())
end

function pl_exp_uninit_seq()
    ccall((:pl_exp_uninit_seq, :libpvcam), rs_bool, ())
end

function pl_dd_get_info(hcam::int16, bytes::int16, text)
    ccall((:pl_dd_get_info, :libpvcam), rs_bool, (int16, int16, Cstring), hcam, bytes, text)
end

function pl_dd_get_info_length(hcam::int16, bytes::Ref{int16})
    ccall((:pl_dd_get_info_length, :libpvcam), rs_bool, (int16, Ref{int16}), hcam, bytes)
end

function pl_dd_get_ver(hcam::int16, dd_version::Ref{uns16})
    ccall((:pl_dd_get_ver, :libpvcam), rs_bool, (int16, Ref{uns16}), hcam, dd_version)
end

function pl_dd_get_retries(hcam::int16, max_retries::Ref{uns16})
    ccall((:pl_dd_get_retries, :libpvcam), rs_bool, (int16, Ref{uns16}), hcam, max_retries)
end

function pl_dd_set_retries(hcam::int16, max_retries::uns16)
    ccall((:pl_dd_set_retries, :libpvcam), rs_bool, (int16, uns16), hcam, max_retries)
end

function pl_dd_get_timeout(hcam::int16, m_sec::Ref{uns16})
    ccall((:pl_dd_get_timeout, :libpvcam), rs_bool, (int16, Ref{uns16}), hcam, m_sec)
end

function pl_dd_set_timeout(hcam::int16, m_sec::uns16)
    ccall((:pl_dd_set_timeout, :libpvcam), rs_bool, (int16, uns16), hcam, m_sec)
end

function pl_ccd_get_adc_offset(hcam::int16, offset::Ref{int16})
    ccall((:pl_ccd_get_adc_offset, :libpvcam), rs_bool, (int16, Ref{int16}), hcam, offset)
end

function pl_ccd_set_adc_offset(hcam::int16, offset::int16)
    ccall((:pl_ccd_set_adc_offset, :libpvcam), rs_bool, (int16, int16), hcam, offset)
end

function pl_ccd_get_chip_name(hcam::int16, chip_name)
    ccall((:pl_ccd_get_chip_name, :libpvcam), rs_bool, (int16, Cstring), hcam, chip_name)
end

function pl_ccd_get_clear_cycles(hcam::int16, clear_cycles::Ref{uns16})
    ccall((:pl_ccd_get_clear_cycles, :libpvcam), rs_bool, (int16, Ref{uns16}), hcam, clear_cycles)
end

function pl_ccd_set_clear_cycles(hcam::int16, clr_cycles::uns16)
    ccall((:pl_ccd_set_clear_cycles, :libpvcam), rs_bool, (int16, uns16), hcam, clr_cycles)
end

function pl_ccd_get_clear_mode(hcam::int16, clear_mode::Ref{int16})
    ccall((:pl_ccd_get_clear_mode, :libpvcam), rs_bool, (int16, Ref{int16}), hcam, clear_mode)
end

function pl_ccd_set_clear_mode(hcam::int16, ccd_clear::int16)
    ccall((:pl_ccd_set_clear_mode, :libpvcam), rs_bool, (int16, int16), hcam, ccd_clear)
end

function pl_ccd_get_color_mode(hcam::int16, color_mode::Ref{uns16})
    ccall((:pl_ccd_get_color_mode, :libpvcam), rs_bool, (int16, Ref{uns16}), hcam, color_mode)
end

function pl_ccd_get_cooling_mode(hcam::int16, cooling::Ref{int16})
    ccall((:pl_ccd_get_cooling_mode, :libpvcam), rs_bool, (int16, Ref{int16}), hcam, cooling)
end

function pl_ccd_get_frame_capable(hcam::int16, frame_capable::Ref{rs_bool})
    ccall((:pl_ccd_get_frame_capable, :libpvcam), rs_bool, (int16, Ref{rs_bool}), hcam, frame_capable)
end

function pl_ccd_get_fwell_capacity(hcam::int16, fwell_capacity::Ref{uns32})
    ccall((:pl_ccd_get_fwell_capacity, :libpvcam), rs_bool, (int16, Ref{uns32}), hcam, fwell_capacity)
end

function pl_ccd_get_mpp_capable(hcam::int16, mpp_capable::Ref{int16})
    ccall((:pl_ccd_get_mpp_capable, :libpvcam), rs_bool, (int16, Ref{int16}), hcam, mpp_capable)
end

function pl_ccd_get_preamp_dly(hcam::int16, preamp_dly::Ref{uns16})
    ccall((:pl_ccd_get_preamp_dly, :libpvcam), rs_bool, (int16, Ref{uns16}), hcam, preamp_dly)
end

function pl_ccd_get_preamp_off_control(hcam::int16, preamp_off_control::Ref{uns32})
    ccall((:pl_ccd_get_preamp_off_control, :libpvcam), rs_bool, (int16, Ref{uns32}), hcam, preamp_off_control)
end

function pl_ccd_set_preamp_off_control(hcam::int16, preamp_off_control::uns32)
    ccall((:pl_ccd_set_preamp_off_control, :libpvcam), rs_bool, (int16, uns32), hcam, preamp_off_control)
end

function pl_ccd_get_preflash(hcam::int16, pre_flash::Ref{uns16})
    ccall((:pl_ccd_get_preflash, :libpvcam), rs_bool, (int16, Ref{uns16}), hcam, pre_flash)
end

function pl_ccd_get_pmode(hcam::int16, pmode::Ref{int16})
    ccall((:pl_ccd_get_pmode, :libpvcam), rs_bool, (int16, Ref{int16}), hcam, pmode)
end

function pl_ccd_set_pmode(hcam::int16, pmode::int16)
    ccall((:pl_ccd_set_pmode, :libpvcam), rs_bool, (int16, int16), hcam, pmode)
end

function pl_ccd_get_premask(hcam::int16, pre_mask::Ref{uns16})
    ccall((:pl_ccd_get_premask, :libpvcam), rs_bool, (int16, Ref{uns16}), hcam, pre_mask)
end

function pl_ccd_get_prescan(hcam::int16, prescan::Ref{uns16})
    ccall((:pl_ccd_get_prescan, :libpvcam), rs_bool, (int16, Ref{uns16}), hcam, prescan)
end

function pl_ccd_get_postmask(hcam::int16, post_mask::Ref{uns16})
    ccall((:pl_ccd_get_postmask, :libpvcam), rs_bool, (int16, Ref{uns16}), hcam, post_mask)
end

function pl_ccd_get_postscan(hcam::int16, postscan::Ref{uns16})
    ccall((:pl_ccd_get_postscan, :libpvcam), rs_bool, (int16, Ref{uns16}), hcam, postscan)
end

function pl_ccd_get_par_size(hcam::int16, par_size::Ref{uns16})
    ccall((:pl_ccd_get_par_size, :libpvcam), rs_bool, (int16, Ref{uns16}), hcam, par_size)
end

function pl_ccd_get_ser_size(hcam::int16, ser_size::Ref{uns16})
    ccall((:pl_ccd_get_ser_size, :libpvcam), rs_bool, (int16, Ref{uns16}), hcam, ser_size)
end

function pl_ccd_get_serial_num(hcam::int16, serial_num::Ref{uns16})
    ccall((:pl_ccd_get_serial_num, :libpvcam), rs_bool, (int16, Ref{uns16}), hcam, serial_num)
end

function pl_ccs_get_status(hcam::int16, ccs_status::Ref{int16})
    ccall((:pl_ccs_get_status, :libpvcam), rs_bool, (int16, Ref{int16}), hcam, ccs_status)
end

function pl_ccd_get_summing_well(hcam::int16, s_well_exists::Ref{rs_bool})
    ccall((:pl_ccd_get_summing_well, :libpvcam), rs_bool, (int16, Ref{rs_bool}), hcam, s_well_exists)
end

function pl_ccd_get_tmp(hcam::int16, cur_tmp::Ref{int16})
    ccall((:pl_ccd_get_tmp, :libpvcam), rs_bool, (int16, Ref{int16}), hcam, cur_tmp)
end

function pl_ccd_get_tmp_range(hcam::int16, tmp_hi_val::Ref{int16}, tmp_lo_val::Ref{int16})
    ccall((:pl_ccd_get_tmp_range, :libpvcam), rs_bool, (int16, Ref{int16}, Ref{int16}), hcam, tmp_hi_val, tmp_lo_val)
end

function pl_ccd_get_tmp_setpoint(hcam::int16, tmp_setpoint::Ref{int16})
    ccall((:pl_ccd_get_tmp_setpoint, :libpvcam), rs_bool, (int16, Ref{int16}), hcam, tmp_setpoint)
end

function pl_ccd_set_tmp_setpoint(hcam::int16, tmp_setpoint::int16)
    ccall((:pl_ccd_set_tmp_setpoint, :libpvcam), rs_bool, (int16, int16), hcam, tmp_setpoint)
end

function pl_ccd_set_readout_port(arg1::int16, arg2::int16)
    ccall((:pl_ccd_set_readout_port, :libpvcam), rs_bool, (int16, int16), arg1, arg2)
end

function pl_ccd_get_pix_par_dist(hcam::int16, pix_par_dist::Ref{uns16})
    ccall((:pl_ccd_get_pix_par_dist, :libpvcam), rs_bool, (int16, Ref{uns16}), hcam, pix_par_dist)
end

function pl_ccd_get_pix_par_size(hcam::int16, pix_par_size::Ref{uns16})
    ccall((:pl_ccd_get_pix_par_size, :libpvcam), rs_bool, (int16, Ref{uns16}), hcam, pix_par_size)
end

function pl_ccd_get_pix_ser_dist(hcam::int16, pix_ser_dist::Ref{uns16})
    ccall((:pl_ccd_get_pix_ser_dist, :libpvcam), rs_bool, (int16, Ref{uns16}), hcam, pix_ser_dist)
end

function pl_ccd_get_pix_ser_size(hcam::int16, pix_ser_size::Ref{uns16})
    ccall((:pl_ccd_get_pix_ser_size, :libpvcam), rs_bool, (int16, Ref{uns16}), hcam, pix_ser_size)
end

function pl_spdtab_get_bits(hcam::int16, spdtab_bits::Ref{int16})
    ccall((:pl_spdtab_get_bits, :libpvcam), rs_bool, (int16, Ref{int16}), hcam, spdtab_bits)
end

function pl_spdtab_get_gain(hcam::int16, spdtab_gain::Ref{int16})
    ccall((:pl_spdtab_get_gain, :libpvcam), rs_bool, (int16, Ref{int16}), hcam, spdtab_gain)
end

function pl_spdtab_set_gain(hcam::int16, spdtab_gain::int16)
    ccall((:pl_spdtab_set_gain, :libpvcam), rs_bool, (int16, int16), hcam, spdtab_gain)
end

function pl_spdtab_get_max_gain(hcam::int16, spdtab_max_gain::Ref{int16})
    ccall((:pl_spdtab_get_max_gain, :libpvcam), rs_bool, (int16, Ref{int16}), hcam, spdtab_max_gain)
end

function pl_spdtab_get_num(hcam::int16, spdtab_num::Ref{int16})
    ccall((:pl_spdtab_get_num, :libpvcam), rs_bool, (int16, Ref{int16}), hcam, spdtab_num)
end

function pl_spdtab_set_num(hcam::int16, spdtab_num::int16)
    ccall((:pl_spdtab_set_num, :libpvcam), rs_bool, (int16, int16), hcam, spdtab_num)
end

function pl_spdtab_get_entries(hcam::int16, spdtab_entries::Ref{int16})
    ccall((:pl_spdtab_get_entries, :libpvcam), rs_bool, (int16, Ref{int16}), hcam, spdtab_entries)
end

function pl_spdtab_get_port(hcam::int16, spdtab_port::Ref{int16})
    ccall((:pl_spdtab_get_port, :libpvcam), rs_bool, (int16, Ref{int16}), hcam, spdtab_port)
end

function pl_spdtab_get_port_total(hcam::int16, total_ports::Ref{int16})
    ccall((:pl_spdtab_get_port_total, :libpvcam), rs_bool, (int16, Ref{int16}), hcam, total_ports)
end

function pl_spdtab_get_time(hcam::int16, spdtab_time::Ref{uns16})
    ccall((:pl_spdtab_get_time, :libpvcam), rs_bool, (int16, Ref{uns16}), hcam, spdtab_time)
end

function pl_shtr_get_close_dly(hcam::int16, shtr_close_dly::Ref{uns16})
    ccall((:pl_shtr_get_close_dly, :libpvcam), rs_bool, (int16, Ref{uns16}), hcam, shtr_close_dly)
end

function pl_shtr_set_close_dly(hcam::int16, shtr_close_dly::uns16)
    ccall((:pl_shtr_set_close_dly, :libpvcam), rs_bool, (int16, uns16), hcam, shtr_close_dly)
end

function pl_shtr_get_open_dly(hcam::int16, shtr_open_dly::Ref{uns16})
    ccall((:pl_shtr_get_open_dly, :libpvcam), rs_bool, (int16, Ref{uns16}), hcam, shtr_open_dly)
end

function pl_shtr_set_open_dly(hcam::int16, shtr_open_dly::uns16)
    ccall((:pl_shtr_set_open_dly, :libpvcam), rs_bool, (int16, uns16), hcam, shtr_open_dly)
end

function pl_shtr_get_open_mode(hcam::int16, shtr_open_mode::Ref{int16})
    ccall((:pl_shtr_get_open_mode, :libpvcam), rs_bool, (int16, Ref{int16}), hcam, shtr_open_mode)
end

function pl_shtr_set_open_mode(hcam::int16, shtr_open_mode::int16)
    ccall((:pl_shtr_set_open_mode, :libpvcam), rs_bool, (int16, int16), hcam, shtr_open_mode)
end

function pl_shtr_get_status(hcam::int16, shtr_status::Ref{int16})
    ccall((:pl_shtr_get_status, :libpvcam), rs_bool, (int16, Ref{int16}), hcam, shtr_status)
end

function pl_exp_get_time_seq(hcam::int16, exp_time::Ref{uns16})
    ccall((:pl_exp_get_time_seq, :libpvcam), rs_bool, (int16, Ref{uns16}), hcam, exp_time)
end

function pl_exp_set_time_seq(hcam::int16, exp_time::uns16)
    ccall((:pl_exp_set_time_seq, :libpvcam), rs_bool, (int16, uns16), hcam, exp_time)
end

function pl_exp_check_progress(hcam::int16, status::Ref{int16}, bytes_arrived::Ref{uns32})
    ccall((:pl_exp_check_progress, :libpvcam), rs_bool, (int16, Ref{int16}, Ref{uns32}), hcam, status, bytes_arrived)
end

function pl_exp_set_cont_mode(hcam::int16, mode::int16)
    ccall((:pl_exp_set_cont_mode, :libpvcam), rs_bool, (int16, int16), hcam, mode)
end

function pl_subsys_do_diag(hcam::int16, subsys_id::uns8, err_code::Ref{uns16})
    ccall((:pl_subsys_do_diag, :libpvcam), rs_bool, (int16, uns8, Ref{uns16}), hcam, subsys_id, err_code)
end

function pl_subsys_get_id(hcam::int16, subsys_id::uns8, part_num::Ref{uns16}, revision::Ref{uns8})
    ccall((:pl_subsys_get_id, :libpvcam), rs_bool, (int16, uns8, Ref{uns16}, Ref{uns8}), hcam, subsys_id, part_num, revision)
end

function pl_subsys_get_name(hcam::int16, subsys_id::uns8, subsys_name)
    ccall((:pl_subsys_get_name, :libpvcam), rs_bool, (int16, uns8, Cstring), hcam, subsys_id, subsys_name)
end

function pl_exp_get_driver_buffer(hcam::int16, pixel_stream::Ref{Ptr{Cvoid}}, byte_cnt::Ref{uns32})
    ccall((:pl_exp_get_driver_buffer, :libpvcam), rs_bool, (int16, Ref{Ptr{Cvoid}}, Ref{uns32}), hcam, pixel_stream, byte_cnt)
end

function pl_buf_init()
    ccall((:pl_buf_init, :libpvcam), rs_bool, ())
end

function pl_buf_uninit()
    ccall((:pl_buf_uninit, :libpvcam), rs_bool, ())
end

function pl_buf_alloc(hbuf::Ref{int16}, exp_total::int16, bit_depth::int16, rgn_total::int16, rgn_array::Ref{rgn_type})
    ccall((:pl_buf_alloc, :libpvcam), rs_bool, (Ref{int16}, int16, int16, int16, Ref{rgn_type}), hbuf, exp_total, bit_depth, rgn_total, rgn_array)
end

function pl_buf_get_exp_date(hbuf::int16, exp_num::int16, year::Ref{int16}, month::Ref{uns8}, day::Ref{uns8}, hour::Ref{uns8}, min::Ref{uns8}, sec::Ref{uns8}, msec::Ref{uns16})
    ccall((:pl_buf_get_exp_date, :libpvcam), rs_bool, (int16, int16, Ref{int16}, Ref{uns8}, Ref{uns8}, Ref{uns8}, Ref{uns8}, Ref{uns8}, Ref{uns16}), hbuf, exp_num, year, month, day, hour, min, sec, msec)
end

function pl_buf_set_exp_date(hbuf::int16, exp_num::int16, year::int16, month::uns8, day::uns8, hour::uns8, min::uns8, sec::uns8, msec::uns16)
    ccall((:pl_buf_set_exp_date, :libpvcam), rs_bool, (int16, int16, int16, uns8, uns8, uns8, uns8, uns8, uns16), hbuf, exp_num, year, month, day, hour, min, sec, msec)
end

function pl_buf_get_exp_time(hbuf::int16, exp_num::int16, exp_msec::Ref{uns32})
    ccall((:pl_buf_get_exp_time, :libpvcam), rs_bool, (int16, int16, Ref{uns32}), hbuf, exp_num, exp_msec)
end

function pl_buf_get_exp_total(hbuf::int16, total_exps::Ref{int16})
    ccall((:pl_buf_get_exp_total, :libpvcam), rs_bool, (int16, Ref{int16}), hbuf, total_exps)
end

function pl_buf_get_img_bin(himg::int16, ibin::Ref{int16}, jbin::Ref{int16})
    ccall((:pl_buf_get_img_bin, :libpvcam), rs_bool, (int16, Ref{int16}, Ref{int16}), himg, ibin, jbin)
end

function pl_buf_get_img_handle(hbuf::int16, exp_num::int16, img_num::int16, himg::Ref{int16})
    ccall((:pl_buf_get_img_handle, :libpvcam), rs_bool, (int16, int16, int16, Ref{int16}), hbuf, exp_num, img_num, himg)
end

function pl_buf_get_img_ofs(himg::int16, s_ofs::Ref{int16}, p_ofs::Ref{int16})
    ccall((:pl_buf_get_img_ofs, :libpvcam), rs_bool, (int16, Ref{int16}, Ref{int16}), himg, s_ofs, p_ofs)
end

function pl_buf_get_img_ptr(himg::int16, img_addr::Ref{Ptr{Cvoid}})
    ccall((:pl_buf_get_img_ptr, :libpvcam), rs_bool, (int16, Ref{Ptr{Cvoid}}), himg, img_addr)
end

function pl_buf_get_img_size(himg::int16, x_size::Ref{int16}, y_size::Ref{int16})
    ccall((:pl_buf_get_img_size, :libpvcam), rs_bool, (int16, Ref{int16}, Ref{int16}), himg, x_size, y_size)
end

function pl_buf_get_img_total(hbuf::int16, totl_imgs::Ref{int16})
    ccall((:pl_buf_get_img_total, :libpvcam), rs_bool, (int16, Ref{int16}), hbuf, totl_imgs)
end

function pl_buf_get_size(hbuf::int16, buf_size::Ref{int32})
    ccall((:pl_buf_get_size, :libpvcam), rs_bool, (int16, Ref{int32}), hbuf, buf_size)
end

function pl_buf_free(hbuf::int16)
    ccall((:pl_buf_free, :libpvcam), rs_bool, (int16,), hbuf)
end

function pl_buf_get_bits(hbuf::int16, bit_depth::Ref{int16})
    ccall((:pl_buf_get_bits, :libpvcam), rs_bool, (int16, Ref{int16}), hbuf, bit_depth)
end

function pl_exp_unravel(hcam::int16, exposure::uns16, pixel_stream::Ref{Cvoid}, rgn_total::uns16, rgn_array::Ref{rgn_type}, array_list::Ref{Ptr{uns16}})
    ccall((:pl_exp_unravel, :libpvcam), rs_bool, (int16, uns16, Ref{Cvoid}, uns16, Ref{rgn_type}, Ref{Ptr{uns16}}), hcam, exposure, pixel_stream, rgn_total, rgn_array, array_list)
end

function pl_exp_wait_start_xfer(hcam::int16, tlimit::uns32)
    ccall((:pl_exp_wait_start_xfer, :libpvcam), rs_bool, (int16, uns32), hcam, tlimit)
end

function pl_exp_wait_end_xfer(hcam::int16, tlimit::uns32)
    ccall((:pl_exp_wait_end_xfer, :libpvcam), rs_bool, (int16, uns32), hcam, tlimit)
end

function pv_cam_get_ccs_mem(hcam::int16, size::Ref{uns16})
    ccall((:pv_cam_get_ccs_mem, :libpvcam), rs_bool, (int16, Ref{uns16}), hcam, size)
end

function pv_cam_send_debug(hcam::int16, debug_str, reply_len::uns16, reply_str)
    ccall((:pv_cam_send_debug, :libpvcam), rs_bool, (int16, Cstring, uns16, Cstring), hcam, debug_str, reply_len, reply_str)
end

function pv_cam_write_read(hcam::int16, c_class::uns8, write_bytes::uns16, write_array::Ref{uns8}, read_array::Ref{uns8})
    ccall((:pv_cam_write_read, :libpvcam), rs_bool, (int16, uns8, uns16, Ref{uns8}, Ref{uns8}), hcam, c_class, write_bytes, write_array, read_array)
end

function pv_dd_active(hcam::int16, pixel_stream::Ref{Cvoid})
    ccall((:pv_dd_active, :libpvcam), rs_bool, (int16, Ref{Cvoid}), hcam, pixel_stream)
end

function pv_exp_get_bytes(hcam::int16, exp_bytes::Ref{uns32})
    ccall((:pv_exp_get_bytes, :libpvcam), rs_bool, (int16, Ref{uns32}), hcam, exp_bytes)
end

function pv_exp_get_script(hcam::int16, script_valid::Ref{rs_bool})
    ccall((:pv_exp_get_script, :libpvcam), rs_bool, (int16, Ref{rs_bool}), hcam, script_valid)
end

function pv_exp_get_status(hcam::int16, status::Ref{int16}, byte_cnt::Ref{uns32}, frame_cnt::Ref{uns32})
    ccall((:pv_exp_get_status, :libpvcam), rs_bool, (int16, Ref{int16}, Ref{uns32}, Ref{uns32}), hcam, status, byte_cnt, frame_cnt)
end

function pv_exp_set_bytes(hcam::int16, frame_count::uns32, seq_bytes::uns32, pixel_stream::Ref{Cvoid})
    ccall((:pv_exp_set_bytes, :libpvcam), rs_bool, (int16, uns32, uns32, Ref{Cvoid}), hcam, frame_count, seq_bytes, pixel_stream)
end

function pv_exp_set_script(hcam::int16, script_valid::rs_bool)
    ccall((:pv_exp_set_script, :libpvcam), rs_bool, (int16, rs_bool), hcam, script_valid)
end

function pv_set_error_code(omode::int16, err_code::int16)
    ccall((:pv_set_error_code, :libpvcam), rs_bool, (int16, int16), omode, err_code)
end

function pv_cam_do_reads(hcam::int16)
    ccall((:pv_cam_do_reads, :libpvcam), rs_bool, (int16,), hcam)
end

function pv_free(block::Ref{Cvoid}, heap::int16)
    ccall((:pv_free, :libpvcam), rs_bool, (Ref{Cvoid}, int16), block, heap)
end

function pv_malloc(size::uns32, heap::int16)
    ccall((:pv_malloc, :libpvcam), Ptr{Cvoid}, (uns32, int16), size, heap)
end

function pv_realloc(block::Ref{Cvoid}, size::uns32, heap::int16)
    ccall((:pv_realloc, :libpvcam), Ptr{Cvoid}, (Ref{Cvoid}, uns32, int16), block, size, heap)
end

function pv_script_set_hook(pfn::Ref{pm_script_hook})
    ccall((:pv_script_set_hook, :libpvcam), rs_bool, (Ref{pm_script_hook},), pfn)
end

function pv_ccd_get_accum_capable(hcam::int16, accum_capable::Ref{rs_bool})
    ccall((:pv_ccd_get_accum_capable, :libpvcam), rs_bool, (int16, Ref{rs_bool}), hcam, accum_capable)
end

function pv_exp_get_frames(hcam::int16, exp_frames::Ref{uns32})
    ccall((:pv_exp_get_frames, :libpvcam), rs_bool, (int16, Ref{uns32}), hcam, exp_frames)
end

function pv_exp_set_frames(hcam::int16, exp_frames::uns32)
    ccall((:pv_exp_set_frames, :libpvcam), rs_bool, (int16, uns32), hcam, exp_frames)
end

function pv_exp_set_no_readout_timeout(hcam::int16)
    ccall((:pv_exp_set_no_readout_timeout, :libpvcam), rs_bool, (int16,), hcam)
end

function pv_exp_reset_no_readout_timeout(hcam::int16)
    ccall((:pv_exp_reset_no_readout_timeout, :libpvcam), rs_bool, (int16,), hcam)
end

function pm_cam_write_read(hcam::int16, c_class::uns8, write_bytes::uns16, write_array::Ref{uns8}, read_array::Ref{uns8})
    ccall((:pm_cam_write_read, :libpvcam), rs_bool, (int16, uns8, uns16, Ref{uns8}, Ref{uns8}), hcam, c_class, write_bytes, write_array, read_array)
end

function pl_ddi_get_ver(ddi_version::Ref{uns16})
    ccall((:pl_ddi_get_ver, :libpvcam), rs_bool, (Ref{uns16},), ddi_version)
end

function pl_cam_get_diags(hcam::int16)
    ccall((:pl_cam_get_diags, :libpvcam), rs_bool, (int16,), hcam)
end

function pl_md_frame_decode(pDstFrame::Ref{md_frame}, pSrcBuf::Ref{Cvoid}, srcBufSize::uns32)
    ccall((:pl_md_frame_decode, :libpvcam), rs_bool, (Ref{md_frame}, Ref{Cvoid}, uns32), pDstFrame, pSrcBuf, srcBufSize)
end

function pl_md_frame_recompose(pDstBuf::Ref{Cvoid}, offX::uns16, offY::uns16, dstWidth::uns16, dstHeight::uns16, pSrcFrame::Ref{md_frame})
    ccall((:pl_md_frame_recompose, :libpvcam), rs_bool, (Ref{Cvoid}, uns16, uns16, uns16, uns16, Ref{md_frame}), pDstBuf, offX, offY, dstWidth, dstHeight, pSrcFrame)
end

function pl_md_create_frame_struct_cont(pFrame::Ref{Ptr{md_frame}}, roiCount::uns16)
    ccall((:pl_md_create_frame_struct_cont, :libpvcam), rs_bool, (Ref{Ptr{md_frame}}, uns16), pFrame, roiCount)
end

function pl_md_create_frame_struct(pFrame::Ref{Ptr{md_frame}}, pSrcBuf::Ref{Cvoid}, srcBufSize::uns32)
    ccall((:pl_md_create_frame_struct, :libpvcam), rs_bool, (Ref{Ptr{md_frame}}, Ref{Cvoid}, uns32), pFrame, pSrcBuf, srcBufSize)
end

function pl_md_release_frame_struct(pFrame::Ref{md_frame})
    ccall((:pl_md_release_frame_struct, :libpvcam), rs_bool, (Ref{md_frame},), pFrame)
end

function pl_md_read_extended(pOutput::Ref{md_ext_item_collection}, pExtMdPtr::Ref{Cvoid}, extMdSize::uns32)
    ccall((:pl_md_read_extended, :libpvcam), rs_bool, (Ref{md_ext_item_collection}, Ref{Cvoid}, uns32), pOutput, pExtMdPtr, extMdSize)
end


text:
using Gadfly
using Cairo
using DataFrames
using Colors

# General plot/data variables
path     = "/home/cns/new_images/" #"/home/cns/Desktop/"
infile   = "f5a.csv"
outfile  = "f5a.pdf"
temp     = "24" #K
logn     = "4" #log(nH2)
title    = "T=$temp K, nH=10$logn cm-3" #ζ=10-17 s-1"
ylabel   = "[HCO+]/[DCO+]" #"[HCO+]/[DCO+]" #"OPR(H2)"  #"nX/nH"
keylabel = "Initial OPR" #"ζ (s-1)"
xmax     = 10^(-14.0)
xmin     = 10^(-18.0)
ymax     = 10^(5.0)
ymin     = 10^(0.0)
obs      = true #true
obsxmin  = xmin
obsxmax  = xmax
obsymin  = 600 #600 #18
obsymax  = 800 #800 #50
plotType = 3

#=
1 = Multiline abundance vs time with color
2 = Several line abundance vs time with color/style
3 = Zetaplot + isoreps
4 = Standard abundance vs time for arbitrary species
=#

# Plot theme variables
plottheme = Gadfly.Theme(
                        line_width=2pt,
                        minor_label_font_size=13pt,
                        minor_label_color=colorant"black",
                        major_label_font_size=15pt,
                        major_label_color=colorant"black",
                        key_label_color=colorant"black",
                        key_title_color=colorant"black",
                        key_title_font_size=15pt,
                        key_label_font_size=13pt,
                        grid_color=colorant"black")

# 1) Multiline abundance vs time w. color
if plotType == 1
  println("Now reading $infile contents")
  ab_df = readtable(
                    path*infile,
                    names = [:Time,:Ratio,:ζ],
                    eltypes = [Float64,Float64,Float64]
  )

  println("Now generating plotType $plotType")
  p1 = plot(
            ab_df[ab_df[:Time].<xmax,:],
            x="Time",
            y="Ratio",
            Scale.x_log10,
            Scale.y_log10,
            Geom.line,
            color = "ζ",
            Guide.colorkey(keylabel),
            Guide.title(title),
            Guide.ylabel(ylabel),
            Guide.xlabel("Time (yr)"),
            Scale.color_log10(colormap=Scale.lab_gradient(
                                                          colorant"darkblue",
                                                          colorant"mediumblue",
                                                          colorant"deepskyblue",
                                                          colorant"turquoise",
                                                          colorant"lightgreen",
                                                          colorant"gold",
#                                                          colorant"yellow"
                                                          ))
            )

  # Apply the theme to the plot
  push!(p1,plottheme)

  println("Now exporting PDF for $outfile")
  draw(PDF(path*outfile,6inch,5inch),p1)

# 2) Few line OPR vs time plot
elseif plotType == 2
  println("Reading in data for $infile")
  ab_df = readtable(
                    path*infile,
                    names = [:Time,:OPR,:InitOPR,:ζ,:Set],
                    eltypes = [Float64,Float64,Float64,Float64,Float64]
                   )

  ab_df[:Set] = Int64[Int64(x) for x in ab_df[:Set]]
  ab_df = ab_df[ab_df[:Time].<xmax,:]

  #Setup the layer dataframes
  println("Setting up dataframe layers")
  l1_df = DataFrame()
  l1_df = ab_df
  l1_df = l1_df[l1_df[:Set] .== 0, :]
  l1 = layer(
             l1_df,
             x="Time",
             y="OPR",
             Geom.line,
             Theme(
                   default_color=colorant"gold",
                   line_width=2pt
                   )
            )

  l2_df = DataFrame()
  l2_df = ab_df
  l2_df = l2_df[l2_df[:Set] .== 1, :]
  l2 = layer(
             l2_df,
             x="Time",
             y="OPR",
             Geom.line,
             Theme(
                   default_color=colorant"gold",
                   line_width=2pt,
                   line_style=Gadfly.get_stroke_vector(:dot)
                   )
            )

  l3_df = DataFrame()
  l3_df = ab_df
  l3_df = l3_df[l3_df[:Set] .== 2, :]
  l3 = layer(
             l3_df,
             x="Time",
             y="OPR",
             Geom.line,
             Theme(
                   default_color=colorant"deepskyblue",
                   line_width=2pt
                   )
            )

  l4_df = DataFrame()
  l4_df = ab_df
  l4_df = l4_df[l4_df[:Set] .== 3, :]
  l4 = layer(
             l4_df,
             x="Time",
             y="OPR",
             Geom.line,
             Theme(
                   default_color=colorant"deepskyblue",
                   line_width=2pt,
                   line_style=Gadfly.get_stroke_vector(:dot)
                   )
            )

  println("Now generating $outfile")
  p2 = plot(
            l1, l2, l3, l4,
            Guide.manual_color_key(
                                   "ζ (s-1)",
                                   ["10-15","10-17"],
                                   ["gold","deepskyblue"]
                                  ),
            Scale.x_log10(maxvalue=xmax),
            Scale.y_log10,
            Guide.title(title),
            Guide.ylabel(ylabel),
            Guide.xlabel("Time (yr)")
           )

  push!(p2,plottheme)
  println("Now exporting $outfile")
  draw(PDF(path*outfile,6inch,5inch),p2)

# 3) Zetaplot + isoreps
elseif plotType == 3
  println("Reading data from $infile")
  ab_df = readtable(
                     path*infile,
                     names = [:ζ, :Ratio, :OPR],
                     eltypes = [Float64, Float64, UTF8String]
                   )

  ab_df = ab_df[xmin.< ab_df[:ζ] .<xmax,:]

  # Make the layers
  println("Now creating layers")
  l1_df  = DataFrame()
  l1_df  = ab_df[ab_df[:OPR].=="Varied",:]
  l1_df  = l1_df[l1_df[:Ratio].>ymin,:]
  println("test")
  varied = layer(
             l1_df,
             x="ζ",
             y="Ratio",
             Geom.point,
             Theme(
                   default_color=colorant"deepskyblue",
                   default_point_size=2pt,
                   colorkey_swatch_shape=:circle
                   )
            )

  l2_df  = DataFrame()
  l2_df  = ab_df[ab_df[:OPR].=="0.01",:]
  l2_df  = l2_df[l2_df[:Ratio].>ymin,:]
  opr0_01 = layer(
             l2_df,
             x="ζ",
             y="Ratio",
             Geom.line,
             Theme(
                   default_color=colorant"goldenrod",
                   colorkey_swatch_shape=:square,
                   line_width=2pt
                   )
            )

  l3_df  = DataFrame()
  l3_df  = ab_df[ab_df[:OPR].=="0.1",:]
  l3_df  = l3_df[l3_df[:Ratio].>ymin,:]
  opr0_1 = layer(
             l3_df,
             x="ζ",
             y="Ratio",
             Geom.line,
             Theme(
                   default_color=colorant"magenta",
                   colorkey_swatch_shape=:square,
                   line_width=2pt
                   )
            )

  l4_df  = DataFrame()
  l4_df  = ab_df[ab_df[:OPR].=="3",:]
  l4_df  = l4_df[l4_df[:Ratio].>ymin,:]
  opr3 = layer(
             l4_df,
             x="ζ",
             y="Ratio",
             Geom.line,
             Theme(
                   default_color=colorant"green",
                   colorkey_swatch_shape=:square,
                   line_width=2pt
                   )
            )

  println("Generating plotType $plotType")
  p3 = plot(
            opr0_01, opr0_1, opr3, varied,
            Guide.manual_color_key(
                                   "$keylabel",
                                   ["Varied","0.01","0.1","3"],
                                   ["deepskyblue","goldenrod","magenta","green"]
                                  ),
            Scale.x_log10(minvalue=xmin, maxvalue=xmax),
            Scale.y_log10(minvalue=ymin, maxvalue=ymax),
            Guide.title(title),
            Guide.ylabel(ylabel),
            Guide.xlabel("ζ (s-1)")
           )

  push!(p3,plottheme)

  if obs == true
    obsLayer = layer(
                     x=[obsxmin,obsxmax,obsxmax,obsxmin],
                     y=[obsymin,obsymin,obsymax,obsymax],
                     Geom.polygon(
                                  preserve_order=true,
                                  fill=true
                                  ),
                     Theme(
                           lowlight_opacity=1000,
                           default_color=colorant"gray"
                     )
                    )
    push!(p3,obsLayer)
  end

  println("Now exporting $outfile")
  draw(PDF(path*outfile,6inch,5inch),p3)
elseif plotType == 4
  println("Now reading $infile")
  ab_df = readtable(
                    path*infile,
                    names = [:Time,:Abundance,:Species],
                    eltypes = [Float64, Float64, UTF8String]
                   )

  ab_df = ab_df[ab_df[:Time].<xmax,:]
  for i in 1:length(ab_df[:Species])
    ab_df[:Species][i] = replace(ab_df[:Species][i],"+","+")
  end

  println("Now generating plotType $plotType")
  p4 = plot(
            ab_df,
            x="Time",
            y="Abundance",
            color="Species",
            Geom.line,
            Guide.colorkey(keylabel),
            Guide.title(title),
            Guide.ylabel(ylabel),
            Guide.xlabel("Time (yr)"),
            Scale.x_log10(minvalue=xmin,maxvalue=xmax),
            Scale.y_log10(minvalue=ymin,maxvalue=ymax)
  )

  push!(p4,plottheme)

  println("Now exporting $outfile")
  draw(PDF(path*outfile,6inch,5inch),p4)
end

println("ENDING SCRIPT")

ext: jl


text:
"""
    svgp_elbo(x, y, gp_params, gp_obj)
Evaluate the stochastic variational Gaussian process elbo for optimization

Returns scalar real value of the elbo
"""
function svgp_elbo(x, y, gp_params::SVGP_params, gp_obj::SVGP_obj)
    n, p = size(x)

    sigsq = exp(gp_params.log_sigma[1])^2

    p_mean, p_sd = pred_vgp(x, gp_obj)

    residuals  = y - p_mean

    if gp_obj.distrib == "gaussian"
        marg_like  = -0.5 * n * log(2.0*π)
        marg_like -=  n * gp_params.log_sigma[1]
        marg_like -=  0.5 * sum( residuals .^ 2 .+ p_sd .^ 2 ) / sigsq
    end

    if gp_obj.distrib == "poisson"
        marg_like = 0
        for ii in 1:16  # TODO: Hard coded num of sample for marginalization for now. Should make an argument.
            stdn_samps    = randn(n)
            loglam_samps  = p_mean + p_sd .* stdn_samps
            marg_like     = (ii-1.0)/ii * marg_like + 1. / ii * sum( y .* loglam_samps - exp.(loglam_samps) - loggamma.(y .+ 1) )
        end
    end

    # This is an exponential prior on sigsq to try to avoid the "all noise"
    #     fit for the GP.
    sigma_prior = -3.0 * gp_params.log_sigma[1]

    nugg_scale = 1.e-6 * ( (2.0 * gp_obj.data.mean_y)^2 + gp_obj.data.var_y)
    if nugg_scale < 1.e-8
        nugg_scale = 1.e-8
    end

    cov_mat_i  = covfn(gp_params.inducing_locs, gp_params.inducing_locs, gp_obj)
    cov_mat_i += I * nugg_scale
    S          = Hermitian(gp_params.inducing_L * transpose(gp_params.inducing_L) )
    inv_mat_i  = inv(cov_mat_i)
    m          = gp_params.inducing_mean

    kl_term = 0.5 * (tr(inv_mat_i * S) + ((-m)'*inv_mat_i*(-m))[1] - gp_obj.n_inducing + logdet(cov_mat_i) - logdet(S))
    # q || p

    return float(gp_obj.data.n) / float(n) * marg_like + sigma_prior - kl_term
end

"""
    svgp_elbo_local(x, y, gp_params, gp_local, global_pred)
Evaluate the stochastic variational Gaussian process elbo as part of the hierarchical SVGP
utilizing the predicted mean and standard deviation from the global SVGP

Returns scalar real value of the elbo
"""
function svgp_elbo_local(x, y, gp_params::SVGP_params, gp_local::SVGP_obj, global_pred)
    prior_mean, prior_sd = global_pred

    elbo = svgp_elbo(x, y, gp_params, gp_local)

    resid = gp_params.inducing_mean - prior_mean

    term5  = -0.5 * size(prior_sd)[1] * log(2.0*π)
    term5 -=  sum( log.(prior_sd) )
    term5 -=  0.5 * sum( resid' * (resid ./ prior_sd) )

    return elbo + term5
end

"""
    svgp_elbo_global(x, y, gp_params, gp_global)
Evaluate the stochastic variational Gaussian process elbo as part of the hierarchical SVGP
Is actually just a call to svgp_elbo, but exists here for clarity

Returns scalar real value of the elbo
"""
function svgp_elbo_global(x, y, gp_params::SVGP_params, gp_global::SVGP_obj)
    return svgp_elbo(x, y, gp_params, gp_global)
end

max_stars_repo_name: ayanbiswas/PRISM

max_issues_repo_name: ayanbiswas/PRISM

max_forks_repo_name: ayanbiswas/PRISM


text:
using InvariantSetApproximation
using Test

@testset "InvariantSetApproximation.jl" begin
    # Write your tests here.
end


text:
function converttodate(s)
    if !ismissing(s)
        return Date("$(year(today())) $(s)", DateFormat("y U d"))
    else
        return missing
    end
end


text:
function CGStep(m1,m2;a=1.,b=1.)
	# m1 = a*m1 + b*m2
	return a*m1 + b*m2
end

function CGStep(m1,m2,h1::Array{Header,1},h2::Array{Header,1};a=1.,b=1.)
	# m1 = a*m1 + b*m2
	return a*m1 + b*m2,h1
end

function CGStep(m1::String,m2::String;a=1.,b=1.)
	# m1 = a*m1 + b*m2

	#tmp = join(["tmp_CGStep_",string(round(Int,rand()*100000))])
	#@compat params = Dict(:a=>a,:b=>b)
	#SeisProcess(m1,m2,tmp,[CGStep],[params],key=["imx";"imy"])
	#SeisCopy(tmp,m1)
	#SeisRemove(tmp)
	d1,h,ext = SeisRead(m1)
	d2,h,ext = SeisRead(m2)
	SeisWrite(m1,a*d1[:,:] + b*d2[:,:],h,ext)
end

function CGStep(m1::Array{String,1},m2::Array{String,1};a=[1. 1. 1.],b=[1. 1. 1.])
	# m1 = a*m1 + b*m2
	for j = 1 : length(m1)
		CGStep(m1[j],m2[j],a=a[j],b=b[j])
	end

end


text:
#=
This file is auto-generated. Do not edit.
=#
"""
    mutable struct Describe <: Edit
        col::Symbol
    end

This DataType is required when multiple DataFrames will be appended into one output file (say, if multiple sheets from an XLSX file are included). Before the DataFrames are appended, a column `col` will be added and filled with the value in the file descriptor. !!!! Does it make sense to have a DataType with one field?

# Arguments
- `col::Symbol`: name of new column
"""
mutable struct Describe <: Edit
    "name of new column"
    col::Symbol
end

function Describe(; col, )
    Describe(col, )
end

"""Get [`Describe`](@ref) `col`."""
get_col(value::Describe) = value.col

"""Set [`Describe`](@ref) `col`."""
set_col!(value::Describe, val) = value.col = val

max_stars_repo_name: matbesancon/SLiDE

max_issues_repo_name: matbesancon/SLiDE

max_forks_repo_name: matbesancon/SLiDE


text:
struct ValidationException <: Exception
    reason::String
end

val_max(val, lim, excl) = (excl ? (val < lim) : (val <= lim))
val_min(val, lim, excl) = (excl ? (val > lim) : (val >= lim))
val_max_length(val, lim) = (length(val) <= lim)
val_min_length(val, lim) = (length(val) >= lim)
val_enum(val, lst) = (val in lst)
function val_enum(val::Vector, lst)
    for v in val
        (v in lst) || return false
    end
    true
end
function val_enum(val::Dict, lst)
    for v in keys(val)
        (v in lst) || return false
    end
    true
end

const MSG_INVALID_API_PARAM = Dict{Symbol,Function}([
    :maximum => (val,excl)->string("must be a value less than ", excl ? "or equal to " : "", val),
    :minimum => (val,excl)->string("must be a value greater than ", excl ? "or equal to " : "", val),
    :maxLength => (len)->string("length must be less than or equal to ", len),
    :minLength => (len)->string("length must be greater than or equal to ", len),
    :maxItems => (val)->string("number of items must be less than or equal to ", val),
    :minItems => (val)->string("number of items must be greater than or equal to ", val),
    :enum => (lst)->string("value is not from the allowed values", lst)
])

const VAL_API_PARAM = Dict{Symbol,Function}([
    :maximum => val_max,
    :minimum => val_min,
    :maxLength => val_max_length,
    :minLength => val_min_length,
    :maxItems => val_max_length,
    :minItems => val_min_length,
    :enum => val_enum
])

function validate_param(param, operation, rule, value, args...)
    # do not validate missing values
    (value === nothing) && return

    VAL_API_PARAM[rule](value, args...) && return

    msg = string("Invalid value ($value) of parameter ", param, " for ", operation, ", ", MSG_INVALID_API_PARAM[rule](args...))
    throw(ValidationException(msg))
end

validate_property(::Type{T}, name::Symbol, val) where {T<:SwaggerModel} = nothing


text:
module Layers

#==================
命名規則
・活性化関数：Sigmoid
・損失関数：Sigmoid_with_CrossEntopy

共通メンバ
・params : 重み，バイアス
・grads : 勾配

共通メソッド
・forward()
・backward()

損失レイヤ
    ・メンバ
        ・t : 教師データ
        ・s : スコア
    ・メソッド
        ・forward() : t=[]ならスコア，あるなら損失を返す

その他
・各レイヤの勾配はコンストラクタ内で生成 -> Model,Timeレイヤと非共有にするため
==================#

#params
abstract type Params end
mutable struct Sigmoid_params <: Params
    params
    grads
    out::Array
end
mutable struct Affine_params <: Params
    params #W,b
    grads #dW,db
    in
end
mutable struct ReLU_params <: Params
    params
    grads
    mask_id
end
mutable struct Tanh_params <: Params
    params
    grads
    out::Array
end
mutable struct Sig_and_loss_params <: Params
    params
    grads
    s::Array #スコア
    t::Array
end
mutable struct mse_params <: Params
    params
    grads
    s::Array
    t::Array
end
mutable struct RNN_params <: Params
    params #Wx,Wh,b
    grads #dWx,dWh,db
    cache #x, h_prev, h_next
    padding #空白データ，TimeRnn，Modelとメモリ共有
end
mutable struct TimeRNN_params <: Params
    params #Wx,Wh,b
    grads #dWx,dWh,db
    layers #複数のRNNレイヤを管理
    h #次のエポックに引き継ぐ
    dh
    stateful
    padding #空白データ，Rnn，Modelとメモリ共有
end
mutable struct TimeAffine_params <: Params
    params #W,b
    grads #dW
    layers #複数のAffineレイヤを管理
end
mutable struct TimeMse_params <: Params
    layers
end
mutable struct LSTM_params <: Params
    params #Wx,Wh,b
    grads #dWx,dWh,db
    cache #x, h_prev, h_next,i,f,g,o,c_next
    padding #空白データ，TimeRnn，Modelとメモリ共有
end
mutable struct TimeLSTM_params <: Params
    params #Wx,Wh,b
    grads #dWx,dWh,db
    layers #複数のRNNレイヤを管理
    h #次のエポックに引き継ぐ
    c
    dh
    stateful
    padding #空白データ，Rnn，Modelとメモリ共有
end

#レイヤコンストラクタ
function Sigmoid()
    out = []
    params = []
    grads = []
    return Sigmoid_params(params,grads,out)
end
function Affine(W::Array{Float64,2},b::Array{Float64,2})
    params = [W,b]
    dW = zeros(Float64,size(W))
    db = zeros(Float64,size(b))
    grads = [dW,db]
    in=[]
    return Affine_params(params,grads,in)
end
function ReLU()
    params = []
    grads = []
    mask_id = []
    return ReLU_params(params,grads,mask_id)
end
function Tanh()
    params = []
    grads = []
    out = []
    return Tanh_params(params,grads,out)
end
function Sigmoid_with_CrossEntropy()
    params = []
    grads = []
    s = []
    t = []
    return Sig_and_loss_params(params,grads,s,t)
end
function Mean_Squared_Error()
    params = []
    grads = []
    s = []
    t = []
    return mse_params(params,grads,s,t)
end
function RNN(Wx::Array{Float64,2},Wh::Array{Float64,2},b::Array{Float64,2},padding)
    #勾配の初期化
    dWx = zeros(size(Wx))
    dWh = zeros(size(Wh))
    db = zeros(size(b))
    #パラメータ，勾配のリスト化
    params = [Wx,Wh,b]
    grads = [dWx,dWh,db]
    cache = []
    return RNN_params(params,grads,cache,padding)
end
function TimeRNN(Wx::Array{Float64,2},Wh::Array{Float64,2},b::Array{Float64,2},stateful::Bool,padding)
    #勾配初期化
    dWx = zeros(size(Wx))
    dWh = zeros(size(Wh))
    db = zeros(size(b))
    #重み，バイアス，勾配をリスト化
    params = [Wx,Wh,b]
    grads = [dWx,dWh,db]
    #その他
    layers = nothing
    dh = nothing
    h = nothing
    return TimeRNN_params(params,grads,layers,h,dh,stateful,padding)
end
function TimeAffine(W::Array{Float64,2},b::Array{Float64,2})
    dW = zeros(size(W))
    db = zeros(size(b))
    params = [W,b]
    grads = [dW,db]
    layers = []
    return TimeAffine_params(params,grads,layers)
end
function TimeMse()
    return TimeMse_params([])
end
function LSTM(Wx::Array{Float64,2},Wh::Array{Float64,2},b::Array{Float64,2},padding)
    #勾配の初期化
    dWx = zeros(size(Wx))
    dWh = zeros(size(Wh))
    db = zeros(size(b))
    #パラメータ，勾配のリスト化
    params = [Wx,Wh,b]
    grads = [dWx,dWh,db]
    cache = []
    return LSTM_params(params,grads,cache,padding)
end
function TimeLSTM(Wx::Array{Float64,2},Wh::Array{Float64,2},b::Array{Float64,2},stateful::Bool,padding)
    #勾配初期化
    dWx = zeros(size(Wx))
    dWh = zeros(size(Wh))
    db = zeros(size(b))
    #重み，バイアス，勾配をリスト化
    params = [Wx,Wh,b]
    grads = [dWx,dWh,db]
    #その他
    layers = nothing
    dh = nothing
    h = nothing
    c = nothing
    return TimeLSTM_params(params,grads,layers,h,c,dh,stateful,padding)
end

#forward
function forward(layer::Affine_params,in)
    layer.in = in #逆伝播に使う
    # println(size(in))
    # println(size(layer.params[1]))
    # println(size(layer.params[2]'))
    return in * layer.params[1] .+ layer.params[2]'
end
function forward(layer::Sigmoid_params,in)
    out = 1.0 ./ (1.0 .+ exp.(-in)) #逆伝播に使う
    layer.out = out
    return out
end
function forward(layer::ReLU_params,in)
    id = findall(in.<=0) #0にするIDを抽出
    layer.mask_id = id
    copy_in = copy(in)
    copy_in[id[1:end]] .= 0

    return copy_in
end
function forward(layer::Tanh_params,in)
    out = tanh.(in)
    layer.out = out

    return out
end
function forward(layer::Sig_and_loss_params,in)
    s = 1.0 ./ (1.0 .+ exp.(-in))
    layer.s = s
    if length(layer.t) == 0
        #ただの推論
        return s
    end
    l = -layer.t .* log.(s) - (1 .-layer.t) .* log.(1 .-s)
    return l
end
function forward(layer::mse_params,in)
    layer.s = in
    if length(layer.t) == 0
        #ただの推論
        return layer.s
    end
    l = sum.(((layer.t-in).^2))/length(layer.t)

    return l
end
function forward(layer::RNN_params,x,h_prev)
    Wx,Wh,b = layer.params
    padding = layer.padding

    t = h_prev*Wh + x*Wx .+ b
    h_next = tanh.(t)

    #x に padding が指定してある場合，h_prevの値をそのまま伝播
    if padding !== nothing
        #インデックス取得
        ids = Tuple.(findall(x->x==padding,x))
        #行番号を取得
        id_cs = first.(ids)
        max,min = extrema(id_cs)
        #h_next に h_prevを代入
        h_next[max:min,:] .= h_prev[max:min,:]
    end

    layer.cache = [x,h_prev,h_next]

    return h_next
end
function forward(layer::TimeRNN_params,xs)
    Wx,Wh,b = layer.params
    #バッチサイズ，ブロック数，入力データ数
    N, T, D = size(xs)
    D, H = size(Wx)

    layer.layers = []
    hs = zeros(Float64,(N,T,H))

    if !layer.stateful || layer.h === nothing
        layer.h = zeros(Float64,(N,H))
    end

    for t in 1:T
        rnn_layer = RNN(Wx,Wh,b,layer.padding)
        layer.h = forward(rnn_layer,xs[:,t,:],layer.h)
        hs[:,t,:] = layer.h
        push!(layer.layers,rnn_layer)
    end

    return hs
end
function forward(layer::TimeAffine_params,hs)
    W,b = layer.params
    dW = layer.grads
    N,T,H = size(hs)
    H,O = size(W)
    ys = zeros(Float64,(N,T,O))

    for t in 1:T
        h = hs[:,t,:]
        affine_layer = Affine(W,b)
        y = forward(affine_layer,h)
        ys[:,t,:] = y
        push!(layer.layers,affine_layer)
    end

    return ys
end
function forward(layer::TimeMse_params,ys,t_data)
    N,T,O = size(ys)
    loss = zeros(Float64,size(ys))

    for t in 1:T
        mse_layer = Mean_Squared_Error()
        mse_layer.t = t_data[:,t,:]
        y = ys[:,t,:]
        loss[:,t,:] = forward(mse_layer,y)
        push!(layer.layers,mse_layer)
    end

    return loss
end
function forward(layer::LSTM_params,x,h_prev,c_prev)
    Wx, Wh, b = layer.params
    N, H = size(h_prev)

    A = x * Wx + h_prev * Wh .+ b

    #slice
    f = A[:, begin:H]
    g = A[:, H+1:2*H]
    i = A[:, 2*H+1:3*H]
    o = A[:, 3*H+1:end]

    f = 1.0 ./ (1.0 .+ exp.(-f)) #Sigmoid
    g = tanh.(g)
    i = 1.0 ./ (1.0 .+ exp.(-i))
    o = 1.0 ./ (1.0 .+ exp.(-o))

    c_next = f .* c_prev + g .* i
    h_next = o .* tanh.(c_next)

    layer.cache = [x, h_prev, c_prev, i, f, g, o, c_next]

    return h_next, c_next

end
function forward(layer::TimeLSTM_params,xs)
    Wx,Wh,b = layer.params
    #バッチサイズ，ブロック数，入力データ数
    N, T, D = size(xs)
    H = size(Wh,1)

    layer.layers = []
    hs = zeros(Float64,(N,T,H))

    if !layer.stateful || layer.h === nothing
        layer.h = zeros(Float64,(N,H))
    end

    if !layer.stateful || layer.c === nothing
        layer.c = zeros(Float64,(N,H))
    end

    for t in 1:T
        rnn_layer = LSTM(Wx,Wh,b,layer.padding)
        layer.h, layer.c = forward(rnn_layer,xs[:,t,:],layer.h,layer.c)
        hs[:,t,:] = layer.h
        push!(layer.layers,rnn_layer)
    end

    return hs
end

#backward
function backward(layer::Affine_params,din)
    layer.grads[1] .= (layer.in)' * din #dW
    return din * (layer.params[1])'
end
function backward(layer::ReLU_params,din)
    din[layer.mask_id[1:end]] .= 0

    return din
end
function backward(layer::Sigmoid_params,din)
    return din .* layer.out .* (1 .- layer.out)
end
function backward(layer::Tanh_params,din)
    return din .* (1 .- layer.out.^2)
end
function backward(layer::Sig_and_loss_params,din)
    return layer.s - layer.t
end
function backward(layer::mse_params,din)
    return (layer.s - layer.t).*(2/length(layer.t))
end
function backward(layer::RNN_params,dh_next)
    Wx, Wh, b = layer.params
    x, h_prev, h_next = layer.cache

    dt = dh_next .* (1 .- h_next .^2)
    db = sum(dt,dims=1)
    dWh = h_prev' * dt
    dh_prev = dt * Wh'
    dWx = x' * dt
    dx = dt * Wx'

    layer.grads .= [dWx,dWh,db]

    return dx,dh_prev
end
function backward(layer::TimeRNN_params,dhs)
    Wx, Wh, b = layer.params
    D, H = size(Wx)

    #dhsの次元数から処理を分岐
    if ndims(dhs) == 2
        #many to one (dhs が (N,H))
        N, H = size(dhs)
        T = length(layer.layers)
        dxs = zeros(Float64,(N,T,D))
        #代入する勾配
        grads = copy(layer.grads)
        grads -= grads #全て0に

        dh = copy(dhs)
        for t in T:-1:1
            rnn_layer = layer.layers[t]
            dx, dh = backward(rnn_layer,dh)
            dxs[:,t,:] = dx

            #各レイヤの勾配合算
            grads += rnn_layer.grads
        end

        #TimeRNN,Modelsの勾配更新-> Model.gradsとメモリ共有しているため同時に更新される
        layer.grads[1][:] = grads[1][:]
        layer.grads[2][:] = grads[2][:]
        layer.grads[3][:] = grads[3][:]

    elseif ndims(dhs) == 3
        #many to many (dhs が (N,T,H))
        N, T, H = size(dhs)
        dxs = zeros(Float64,(N,T,D))

        dh = zeros(Float64,size(dhs[:,1,:]))
        for t in T:-1:1
            rnn_layer = layer.layers[t]
            dx, dh = backward(rnn_layer,dhs[:,t,:]+dh)
            dxs[:,t,:] = dx

            #勾配合算 -> Model.gradsとメモリ共有しているため同時に更新される
            for i in 1:3
                layer.grads[i] .+= rnn_layer.grads[i]
            end
        end
    end

    layer.dh = dh

    return dxs

end
function backward(layer::TimeAffine_params,dys)
    N, T, O = size(dys)
    H, O = size(layer.layers[1].params[1]) #W
    dhs = zeros(Float64,(N,T,H))

    for t in 1:T
        dh = zeros(Float64,(N,H))
        affine_layer = layer.layers[t]
        dh = backward(affine_layer,dys[:,t,:])
        dhs[:,t,:] = dh
        #勾配合算 -> Model.gradsとメモリ共有しているため同時に更新される
        for i in 1:2
            layer.grads[i] .+= affine_layer.grads[i]
        end
    end

    return dhs
end
function backward(layer::TimeMse_params,dloss)
    N, T, O = size(dloss)
    dys = zeros(Float64,(N,T,O))

    for t in 1:T
        dy = zeros(Float64,(N,O))
        dy = backward(layer.layers[t],0)
        dys[:,t,:] = dy
    end

    return dys
end
function backward(layer::LSTM_params,dh_next,dc_next)
    Wx, Wh, b = layer.params
    x, h_prev, c_prev, i, f, g, o, c_next = layer.cache

    tanh_c_next = tanh.(c_next)

    ds = dc_next + (dh_next .* o) .* (1 .- tanh_c_next.^2)

    dc_prev = ds .* f

    di = ds .* g
    df = ds .* c_prev
    d_o = dh_next .* tanh_c_next
    dg = ds .* i

    di .*= i .* (1 .- i)
    df .*= f .* (1 .- f)
    d_o .*= o .* (1 .- o)
    dg .*= (1 .- g.^2)

    dA = hcat(df,dg,di,d_o)

    dWh = h_prev' * dA
    dWx = x' * dA
    db = sum(dA,dims=1)

    layer.grads[1][:] = dWx
    layer.grads[2][:] = dWh
    layer.grads[3][:] = db

    dx = dA * Wx'
    dh_prev = dA * Wh'

    return dx, dh_prev, dc_prev
end
function backward(layer::TimeLSTM_params,dhs)
    Wx, Wh, b = layer.params
    D, H = size(Wx)

    #dhsの次元数から処理を分岐
    if ndims(dhs) == 2
        #many to one (dhs が (N,H))
        N, H = size(dhs)
        T = length(layer.layers)
        dxs = zeros(Float64,(N,T,D))
        #代入する勾配
        grads = copy(layer.grads)
        grads -= grads #全て0に

        dh = copy(dhs)
        dc = zeros(Float64,size(dh))

        for t in T:-1:1
            rnn_layer = layer.layers[t]
            dx, dh, dc = backward(rnn_layer,dh,dc)
            dxs[:,t,:] = dx

            #各レイヤの勾配合算
            grads += rnn_layer.grads
        end

        #TimeRNN,Modelsの勾配更新-> Model.gradsとメモリ共有しているため同時に更新される
        layer.grads[1][:] = grads[1][:]
        layer.grads[2][:] = grads[2][:]
        layer.grads[3][:] = grads[3][:]

    elseif ndims(dhs) == 3
        #many to many (dhs が (N,T,H))
        N, T, H = size(dhs)
        dxs = zeros(Float64,(N,T,D))

        dh = zeros(Float64,size(dhs[:,1,:]))
        dc = zeros(Float64,size(dhs[:,1,:]))
        for t in T:-1:1
            rnn_layer = layer.layers[t]
            dx, dh, dc = backward(rnn_layer,dhs[:,t,:]+dh, dc)
            dxs[:,t,:] = dx

            #勾配合算 -> Model.gradsとメモリ共有しているため同時に更新される
            for i in 1:3
                layer.grads[i] .+= rnn_layer.grads[i]
            end
        end
    end

    layer.dh = dh

    return dxs

end

#TimeRNN functions
function set_state(layer::TimeRNN_params,h)
    layer.h = h
end
function reset_state(layer::TimeRNN_params)
    layer.h = nothing
end

function reset_state(layer::TimeLSTM_params)
    layer.h = nothing
    layer.c = nothing
end

end


text:
using HorizonSideRobots

function revers(side::HorizonSide)
    side = HorizonSide((Int(side)+2)%4)
    return side
end

function c_move!(r, side::HorizonSide, c)
    for i = 1:c
        move!(r,side)
    end
end

function movements_to_side!(r, side::HorizonSide)
    c = 0
    while isborder(r,side) == 0
        move!(r,side)
        c += 1
    end
    return c
end

function corner(r)
    x = 0
    y = 0
    while (isborder(r,Sud) == 0) || (isborder(r,West) == 0)
        y = y + movements_to_side!(r,Sud)
        x = x + movements_to_side!(r,West)
    end
    return x, y
end

function go_home!(r,x,y)
    corner(r)
    c_move!(r,Nord,y)
    c_move!(r,Ost,x)
end

function stripe(side,n,x,y,r)
    while isborder(r,side) == 0
        move!(r,side)
        if side == Ost
            x = x + 1;
        else
            x = x - 1;
        end
        draw(r,x,y,n)
    end
    return x,y
end

function draw(r,x,y,n)
    if ((x ÷ n) + (y ÷ n)) % 2 == 0
        putmarker!(r)
    end
end

function chess(r,n)
    z = 0
    m = 0
    z, m = corner(r)
    side = Ost;
    x = 0;
    y = 0;
    if ((x ÷ n) + (y ÷ n)) % 2 == 0
        putmarker!(r)
    end
    while isborder(r,Nord) == 0
        x, y = stripe(side,n,x,y,r)
        move!(r,Nord);
        y += 1;
        side = revers(side);
        draw(r,x,y,n)
    end
    x,y = stripe(side,n,x,y,r)
    go_home!(r,z,m)
end

n = 4

chess(r,n)

max_stars_repo_name: Cheburkova/mirea-progs

max_issues_repo_name: Cheburkova/mirea-progs

max_forks_repo_name: Cheburkova/mirea-progs


text:
@testset "StackedLSTM" begin
    x = rand(Float32, 20)
    for m in (FluxArchitectures.StackedLSTM(20, 10, 3, 1), FluxArchitectures.StackedLSTM(20, 10, 3, 2),
        FluxArchitectures.StackedLSTM(20, 10, 3, 5))
        @test size(m(x)) == (10,)
    end
    @test repr(FluxArchitectures.StackedLSTM(20, 10, 3, 1)) == "Recur(LSTMCell(20, 10))"
    @test repr(FluxArchitectures.StackedLSTM(20, 10, 3, 2)) == "StackedLSTM(20, 10, 3, 2)"
    m = FluxArchitectures.StackedLSTM(20, 10, 3, 5)
    FluxArchitectures.initialize_bias!(m)
    @test all([all(m.chain[i].cell.b .== 1) for i in 1:length(m.chain)])
end

@testset "HiddenRecur" begin
    x = rand(Float32, 20, 100)
    m = FluxArchitectures.HiddenRecur(Flux.LSTMCell(20, 10))
    @test size(m(x)[1]) == (10, 100)
    @test size(m(x)[2]) == (10, 100)
    m = FluxArchitectures.HiddenRecur(Flux.GRUCell(20, 10))
    @test size(m(x)) == (10, 100)
    @test repr(m) == "HiddenRecur(GRUCell(20, 10))"
end

@testset "Sequentialize" begin
    x = rand(Float32, 20, 100)
    m = FluxArchitectures.Seq(LSTM(20, 10))
    @test repr(m) == "Seq(Recur(LSTMCell(20, 10)))"
    @test size(m(x)) == (10, 100)
    m = FluxArchitectures.Seq(FluxArchitectures.HiddenRecur(Flux.LSTMCell(20, 10)))
    @test size(m(x)[1]) == (10, 100)
    @test size(m(x)[2]) == (10, 100)
    m = FluxArchitectures.SeqSkip(Flux.LSTMCell(20, 10), 10)
    @test repr(m) == "SeqSkip(LSTMCell(20, 10))"
    @test size(m(x)) == (10, 100)
    m = FluxArchitectures.SeqSkip(Flux.GRUCell(20, 10), 10)
    @test size(m(x)) == (10, 100)
end

max_stars_repo_name: sdobber/FluxArchitectures

max_issues_repo_name: sdobber/FluxArchitectures

max_forks_repo_name: sdobber/FluxArchitectures


text:
# To run this script, `cd` to the `./test/fixtures` directory and then, from the Julia terminal, `include("./runner.jl")`.

import JSON

function gen( x, name )
	y = Array( Any, length( x ) );
	for i in eachindex(x)
		y[i] = bits( convert( UInt8, x[i] ) );
	end

	data = Dict([
		("x", x),
		("expected", y)
	]);

	outfile = open( name, "w" );
	write( outfile, JSON.json(data) );
	close( outfile );
end

# Integer values:
x = linspace( 0, 255, 256 )
gen( x, "data.json" );


text:
#import Base: length, getindex

struct GeneratorsSet{F <: AbstractComplexInvertibleFunction}
  functions::Vector{F}
  numregular::Int64

  function GeneratorsSet{F}(gs::Vector{F}) where F <: AbstractComplexInvertibleFunction
    funs = (F)[] # Vector{F}
    autoinverses = (F)[] # Vector{F}

    for f in gs
      if f isa AbstractMobiusTransformation && !(f isa InversionReflection)
        push!(funs, f)
      else
        push!(autoinverses, f)
      end # if
    end # for

    funsinv = [inverse(f) for f in funs]
    funs = append!(funs, funsinv)
    nfirstsfuns = length(funs)
    append!(funs, autoinverses)

    new(funs, nfirstsfuns)
  end # constructor GeneratorsSet
end # struct GeneratorsSet

GeneratorsSet(gs::Vector{F}) where F <: AbstractComplexInvertibleFunction =
  GeneratorsSet{F}(gs)

function inverseindex(gs::GeneratorsSet, n::Int)
  if n > gs.numregular
    return n
  end
  ((n + (gs.numregular ÷ 2) - 1) % gs.numregular) + 1
end

Base.getindex(gs::GeneratorsSet, i::Int) = gs.functions[i]
Base.firstindex(gs::GeneratorsSet) = gs.functions[begin]
Base.lastindex(gs::GeneratorsSet) = gs.functions[end]

size(gs::GeneratorsSet) = length(gs.functions)
numregulartransformations(gs::GeneratorsSet) = gs.numregular
numregulartransformationsnoinverses(gs::GeneratorsSet) = gs.numregular÷2
numautoinverses(gs::GeneratorsSet) = length(gs.functions) - gs.numregular
numgenerators(gs::GeneratorsSet) = (gs.numregular÷2) + numautoinverses(gs)

function applypaired(genset::GeneratorsSet, level::Int, levels::Int, objects::Vector, procedure::Function)
  newobjects = []
  newtags = Int[]

  for n in 1:size(genset)
    newset = []
    invindex = inverseindex(genset, n)

    for oindex in 1:length(objects)
      if oindex != invindex # if object not paired with inverse
        o = genset[n](objects[oindex])
        push!(newset, o)
      end
    end # for levelobjects

    procedure(newset, n, level, levels) # procedure on objects Vector
    push!(newobjects, newset)
    push!(newtags, n)
  end # for genset

  newobjects, newtags
end

function traversegroupfirstdepth(generators::Vector{F}, levels::Int, object,
  procedure::Function, paired::Bool=false) where F <: AbstractComplexInvertibleFunction

  #println("- Level 1, gen 0")
  procedure(object, 0, 1, levels) # Level 1: Identity transformation ("generator index = 0")

  if levels <= 1
    return
  end

  genset = GeneratorsSet(generators)

  if paired # object is a vector of elements paired with the transformations
    objects, tags = applypaired(genset, 2, levels, object, procedure)
    if levels <= 2
      return
    end
    for n in 1:size(genset) # Level 3
      invindex = inverseindex(genset,n)
      for k in 1:length(objects)
        if k != invindex
          traversedepth(genset, n, 3, levels, genset[n](objects[k]), procedure)
        end
      end
    end
  else # else paired
    for n in 1:size(genset) # Level 2: Apply transformations first time
      traversedepth(genset, n, 2, levels, genset[n](object), procedure)
    end
  end # if else paired
end

function traversedepth(genset::GeneratorsSet, genindex::Int, level::Int,
  levels::Int, object, procedure::Function)

  #println("-"^level * " Level $level, gen $genindex")
  procedure(object, genindex, level, levels)

  if level == levels
    return
  end

  N = size(genset)
  invindex = inverseindex(genset, genindex)

  # Traverse group (Cayley graph) to lower nodes,
  # but avoiding the corresponding inverse node

  for n in (invindex+1):N
    traversedepth(genset, n, level+1, levels, genset[n](object), procedure)
  end

  for n in 1:(invindex-1)
    traversedepth(genset, n, level+1, levels, genset[n](object), procedure)
  end
end

function traversegroupfirstdepthcomp(generators::Vector{F}, levels::Int,
  procedure::Function) where F <: AbstractMobiusTransformation

  #for g in generators
  #  procedure(g, 0, 1, levels) # Level 1: Identity transformation ("generator index = 0")
  #end

  if levels <= 0
    return
  end

  genset = GeneratorsSet(generators)

  for n in 1:length(generators)
    traversedepthcomp(genset, n, 1, levels, genset[n], procedure)
  end
end

function traversedepthcomp(genset::GeneratorsSet{F}, genindex::Int, level::Int,
  levels::Int, T::F, procedure::Function) where F <: AbstractMobiusTransformation

  procedure(T, genindex, level, levels)

  if level == levels
    return
  end

  N = size(genset)
  invindex = inverseindex(genset, genindex)

  # Traverse group (Cayley graph) to lower nodes,
  # but avoiding the corresponding inverse node and auto iteratives g^n

  for n in (invindex+1):N
    #if n != genindex
      traversedepthcomp(genset, n, level+1, levels, genset[n]∘T, procedure)
    #end
  end

  for n in 1:(invindex-1)
    #if n != genindex
      traversedepthcomp(genset, n, level+1, levels, genset[n]∘T, procedure)
    #end
  end
end

function traversesemigroup(generators::Vector{F}, levels::Int, object,
  procedure::Function) where F <: AbstractMobiusTransformation

  procedure(object, 0, 1, levels)

  for n in 1:length(generators)
    traversesemigroup(generators, n, 1, levels, generators[n](object), procedure)
  end
end

function traversesemigroup(generators::Vector{F}, genindex::Int, level::Int,
  levels::Int, object, procedure::Function) where F <: AbstractMobiusTransformation

  procedure(object, genindex, level, levels)

  if level == levels
    return
  end

  for n in length(generators)
    traversesemigroup(generators, n, level+1, levels, generators[n](object), procedure)
  end
end

function traversegroupfirstbreath(generators::Vector{F}, levels::Int, object,
  procedure::Function, paired::Bool=false) where F <: AbstractComplexInvertibleFunction

  procedure(object, 0, 1, levels) # Level 1: Identity transformation ("generator index = 0")

  if levels <= 1
    return
  end

  genset = GeneratorsSet(generators)
  N = size(genset)

  currentlevel = 2

  newobjects = [object]
  newtags = [0]

  if paired
    newobjects, newtags = applypaired(genset, currentlevel, levels, object, procedure)
    #newobjects = [object]
    currentlevel = 3
  end # if paired

  if levels < currentlevel
    return
  end

  for l in currentlevel:levels
    levelobjects = newobjects
    leveltags = newtags
    newobjects = []
    newtags = Int[]

    for oindex in 1:length(levelobjects)
      for n in 1:N
        invindex = inverseindex(genset, n)

        if leveltags[oindex] == invindex
          continue
        end

        o = genset[n](levelobjects[oindex])
        procedure(o, n, l, levels)
        push!(newobjects, o)
        push!(newtags, n)
      end # for genset
    end # for levelobjects

    empty!(levelobjects)
    empty!(leveltags)
  end # for levels

  empty!(newobjects)
  empty!(newtags)

end # function traversebreath


text:
module OSPropE
  # Function to call the GUI
  export OSPropEGUI

  # Include the main file .fl
  include("mainGUI_OSPropE.jl")
end


text:
Pkg.update()

# Package Development
Pkg.add("PkgDev")

# Jupyter Kernel
Pkg.add("IJulia")

# ALL OF THE PLOTTING!!!!
Pkg.add("PyPlot")
Pkg.add("Gadfly")
Pkg.add("GR")
Pkg.add("Hiccup")
Pkg.add("Plots")
Pkg.add("StatPlots")

# Graphics File Formats
Pkg.add("Cairo")

# Networks
Pkg.add("LightGraphs")

# Calling Python
Pkg.add("PyCall")

# Data Analysis
Pkg.add("DataFrames")
Pkg.add("CSV")
Pkg.add("RDatasets")
Pkg.add("StatsBase")
Pkg.add("HypothesisTests")

max_stars_repo_name: ELIFE-ASU/meet-julia

max_issues_repo_name: ELIFE-ASU/meet-julia

max_forks_repo_name: ELIFE-ASU/meet-julia


text:
select(::Missing, elements_per_dim...; insval = 0) = missing
select(pars::TrackedArray, elements_per_dim...; insval = 0) = param(select(pars.data, elements_per_dim..., insval=insval))

"""
    select(pars::AbstractArray{T,N}, elements_per_dim...; insval = 0) where {T, N}

Return a new `AbstractArray{T, N}` which has a subset of the elements of `pars`.

Which elements to select is determined by `elements_per_dim` which is a `Pair{Int, Vector{Int}}` mapping dimension (first memeber) to which elements to select in that dimension (second memeber).

For a single `dim=>elems` pair, the following holds: `selectdim(output, dim, i) == selectdim(pars, dim, elems[i])` if `elems[i]` is positive and `selectdim(output, dim, i) .== insval` if `elems[i]` is negative.

# Examples
```julia-repl
julia> using NaiveNASflux

julia> pars = reshape(1:3*5, 3,5)
3×5 reshape(::UnitRange{Int64}, 3, 5) with eltype Int64:
 1  4  7  10  13
 2  5  8  11  14
 3  6  9  12  15

 julia> NaiveNASflux.select(pars, 1 => [-1, 1,3,-1,2], 2=>[3, -1, 2], insval=-1)
 5×3 Array{Int64,2}:
  -1  -1  -1
   7  -1   4
   9  -1   6
  -1  -1  -1
   8  -1   5
```
"""
function select(pars::AbstractArray{T,N}, elements_per_dim...; insval = 0) where {T, N}
    psize = collect(size(pars))
    assign = repeat(Any[Colon()], N)
    access = repeat(Any[Colon()], N)

    for de in elements_per_dim
        dim = de.first
        elements = de.second

        indskeep = filter(ind -> ind > 0, elements)
        newmap = elements .> 0

        psize[dim] = length(newmap)
        assign[dim] = findall(newmap)
        access[dim] = indskeep
    end
    newpars = fill!(similar(pars, psize...), T(0)) .+ T(insval)
    newpars[assign...] = pars[access...]
    return newpars
end

"""
    KernelSizeAligned(Δsize)
    KernelSizeAligned(Δs::Integer...)

Strategy for changing kernel size of convolutional layers where filters remain phase aligned. In other words, the same element indices are removed/added for all filters and only 'outer' elements are dropped or added.
"""
struct KernelSizeAligned{T, P}
    Δsize::T
    pad::P
end
KernelSizeAligned(Δs::Integer...;pad = ntuple(i -> 0, length(Δs))) = KernelSizeAligned(Δs, pad)

(s::KernelSizeAligned)(l) = selectfilters(layertype(l), l, s)

otherpars(s::KernelSizeAligned, l) = paddingfor(layertype(l), s)
paddingfor(t, s) = ()
paddingfor(::FluxConvolutional, s) = (pad = s.pad,)

selectfilters(t, l, s) = ()
selectfilters(::FluxConvolutional, l, s) = selectfilters(s, weights(l))

function selectfilters(s::KernelSizeAligned, pars)
    csize = size(pars)
    mids = csize ./ 2 .+ 0.5
    byfun(dim) = i -> abs(mids[dim] - i) * 1 / (1 + mean(abs.(selectdim(pars, dim, i))))
    ps = Pair{Int, Vector{Int}}[]
    for (dim, Δsize) in enumerate(s.Δsize)
        if Δsize < 0
            els = sort(partialsort(1:csize[dim], 1:csize[dim]+Δsize, by=byfun(dim)))
            push!(ps, dim => els)
        elseif Δsize > 0
            els = -ones(Int, csize[dim] + Δsize)
            offs = Δsize ÷ 2
            els[offs+1:csize[dim]+offs] = 1:csize[dim]
            push!(ps, dim => els)
        end
    end
    return ps
end


text:
include("basic.jl")
include("graphing.jl")
include("drawing.jl")
include("fractal-tree.jl")
include("SnakeGame/main.jl")


text:
# ---
# title: 1447. Simplified Fractions
# id: problem1447
# author: zhwang
# date: 2022-02-10
# difficulty: Medium
# categories: Math
# link: <https://leetcode.com/problems/simplified-fractions/description/>
# hidden: true
# ---
#
# Given an integer `n`, return a list of all **simplified** fractions between 0
# and 1 (exclusive) such that the denominator is less-than-or-equal-to `n`. The
# fractions can be in **any** order.
#
#
#
# **Example 1:**
#
#
#
#     Input: n = 2
#     Output: ["1/2"]
#     Explanation: "1/2" is the only unique fraction with a denominator less-than-or-equal-to 2.
#
# **Example 2:**
#
#
#
#     Input: n = 3
#     Output: ["1/2","1/3","2/3"]
#
#
# **Example 3:**
#
#
#
#     Input: n = 4
#     Output: ["1/2","1/3","1/4","2/3","3/4"]
#     Explanation: "2/4" is not a simplified fraction because it can be simplified to "1/2".
#
# **Example 4:**
#
#
#
#     Input: n = 1
#     Output: []
#
#
#
#
# **Constraints:**
#
#   * `1 <= n <= 100`
#
#
## @lc code=start
using LeetCode

simplified_fractions(n::Int) = ["$p/$q" for q in 2:n for p in 1:(q - 1) if gcd(p, q) == 1]
## @lc code=end


text:
using DashBootstrapComponents

progress = dbc_progress(value = 75, striped = true);

max_stars_repo_name: glsdown/dash-bootstrap-components

max_issues_repo_name: glsdown/dash-bootstrap-components

max_forks_repo_name: glsdown/dash-bootstrap-components


text:
################################ MACKEYGLASS ###################################
#   Author : J.Courtois                                                        #
#   This script generates a Mackey-Glass time series using the 4th order       #
#   Runge-Kutta method. The code is a straighforward translation in Julia      #
#   of Matlab code, available here :                                           #
#   https://ww2.mathworks.cn/matlabcentral/fileexchange/24390-mackey-glass-    #
#   time-series-generator?s_tid=prof_contriblnk                                #
################################################################################

"""
    mackeyglass_eq(x_t, x_t_minus_tau, a , b)

"""
mackeyglass_eq(x_t, x_t_minus_tau, a, b) =
    -b*x_t + a*x_t_minus_tau/(1 + x_t_minus_tau^10.0);

"""
    mackeyglass_rk4(x_t, x_t_minus_tau, deltat a , b)

"""
function mackeyglass_rk4(x_t, x_t_minus_tau, deltat, a, b)
    k1 = deltat*mackeyglass_eq(x_t,          x_t_minus_tau, a, b);
    k2 = deltat*mackeyglass_eq(x_t+0.5*k1,   x_t_minus_tau, a, b);
    k3 = deltat*mackeyglass_eq(x_t+0.5*k2,   x_t_minus_tau, a, b);
    k4 = deltat*mackeyglass_eq(x_t+k3,       x_t_minus_tau, a, b);
    return (x_t + k1/6 + k2/3 + k3/3 + k4/6);
end

"""
    T,X = MGGenerator()

Advanced : T,X = MGGenerator(;sample_n, x0, deltat, tau, a, b)

By default :\n
`a = 0.2`     # value for a in eq (1)\n
`b = 0.1`     # value for b in eq (1)\n
`tau = 17`		# delay constant in eq (1)\n
`x0 = 1.2`		# initial condition: x(t=0)=x0\n
`deltat = 0.1`	    # time step size (which coincides with the integration step)\n
`sample_n = 12000`	# total no. of samples, excluding the given initial condition\n
"""
function MGGenerator(;sample_n = 12000, x0 = 1.2, deltat = 0.1, tau = 17,
    timeStep= 0, a = 0.2, b = 0.1)
    X, T, x0, deltat, tau, x_history, x_t, index = MGInit(;sample_n = sample_n,
        timeStep = timeStep, x0 = x0, deltat = deltat, tau = tau,
        a = a, b = b, xwidth = 1)
    for i = 2:sample_n+1
        X[i], x_t, x_history, index, T[i] = MGStep(x_t,x_history, T[i-1],
            index; deltat = deltat, tau = tau, a = a, b = b)
    end
    return T,X
end

"""
    X[i], x_t, x_history, index, T[i] = MGStep(x_t,x_history, T[i-1],index)

Advanced : `X[i], x_t, x_history, index, T[i] = MGStep(x_t,x_history, T[i-1], index; deltat, tau, a, b)`

By default :\n
`a = 0.2`     # value for a in eq (1)\n
`b = 0.1`     # value for b in eq (1)\n
`tau = 17`		# delay constant in eq (1)\n
`deltat = 0.1`	    # time step size (which coincides with the integration step)\n
"""
function MGStep(x_t, x_history, timeStep, index; deltat = 0.1,
                tau = 17, a = 0.2, b = 0.1)
    if tau == 0
        x_t_minus_tau = 0.0;
    else
        x_t_minus_tau = x_history[index]
    end
    x_t_plus_deltat = mackeyglass_rk4(x_t, x_t_minus_tau, deltat, a, b);

    if (tau != 0)
        x_history[index] = x_t_plus_deltat;
        nextIndex = mod(index, length(x_history))+1;
    end
    nextTime = timeStep + deltat;

    return x_t, x_t_plus_deltat, x_history, nextIndex, nextTime
end

"""
    X, T, x0, deltat, tau, x_history, x_t, index = MGInit()

Fixe all variables to run an `MGStep(...)`

Advanced : `MGInit(; sample_n = 12000, timeStep = 0,
        x0 = 1.2, deltat = 0.1, tau = 17, a = 0.2, b = 0.1)
"""
function MGInit(; sample_n = 12000, timeStep = 0,
        x0 = 1.2, deltat = 0.1, tau = 17, a = 0.2, b = 0.1,
        xwidth = 1, X = zeros(sample_n+1, xwidth) .* NaN)
    history_length = Int64(floor(tau/deltat))
    x_history = zeros(history_length) # here we assume x(t)=0 for -tau <= t < 0
    x_t = x0;
    #X = zeros(sample_n+1, xwidth) .* NaN; # vector of all generated x samples
    # there is two
    T = zeros(sample_n+1, 1); # vector of time samples
    T[1] = timeStep
    [X[1,i] = x0 for i=1:xwidth]
    return X, T, x0, deltat, tau, x_history, x_t, 1
end

#Exemple ( Need Plots )
#using Plots
#T,X = MGGenerator()
#plot(T, X, label = "Mackey Glass")


text:
using Catlab, Catlab.Theories
using Catlab.CategoricalAlgebra
using Catlab.WiringDiagrams
using Catlab.Graphics
using Catlab.Graphics.Graphviz
using Catlab.Programs
using Catlab.WiringDiagrams

draw(d::WiringDiagram) = to_graphviz(d,
  orientation=LeftToRight,
  labels=false, label_attr=:xlabel,
  node_attrs=Graphviz.Attributes(
    :fontname => "Courier",
  ),
  edge_attrs=Graphviz.Attributes(
    :fontname => "Courier",
  )
)

to_diagram(x) = add_junctions!(to_wiring_diagram(x))

normal_form(x) = to_hom_expr(FreeCartesianCategory, to_diagram(x))

#julia function composition
∘(f::Function, g::Function) = x->f(g(x))

@present Circuit(FreeCartesianCategory) begin
    Bool::Ob
    NOR::Hom(Bool⊗Bool, Bool)
    NOT::Hom(Bool, Bool)
    AND::Hom(Bool⊗Bool, Bool)
    OR::Hom(Bool⊗Bool, Bool)
    NAND::Hom(Bool⊗Bool, Bool)
end

B = Ob(FreeCartesianCategory, :Bool)
NAND = Hom(:NAND, B⊗B,B)
Dup = mcopy(B)
NOT = Hom(:NOT, B, B)
AND = Hom(:AND, B⊗B, B)
OR = Hom(:OR, B⊗B, B)
NOR = Hom(:NOR, B⊗B,B)

#function that turns basic gates into a boolean(vector) function
function gate_to_bool_func(gate::Catlab.Theories.FreeCartesianCategory.Hom{:generator})::Function
    if gate == NOT
        return NOT_EVAL(vec) = [!(vec[1])]
    elseif gate == AND
        return AND_EVAL(vec) = [vec[1]&&vec[2]]
    elseif gate == OR
        return OR_EVAL(vec) = [vec[1]||vec[2]]
    elseif gate == NAND
        return NAND_EVAL(vec) = [!(vec[1]&&vec[2])]
    elseif gate == NOR
        return NOR_EVAL(vec) = [!(vec[1]||vec[2])]
    end
end

#function that returns the number of input wires for basic gates
function gate_input(gate::Catlab.Theories.FreeCartesianCategory.Hom{:generator})::Int
    if gate == NOT
        return 1
    else
        return 2
    end
end

#function that returns the number of input wires for circuits
function circ_input(circ::Catlab.Theories.FreeCartesianCategory.Hom)::Int

    input = 0
    argvec = args(circ)
    len = length(argvec)

    if head(circ) == :compose
        input = circ_input(argvec[1])

    elseif head(circ) == :otimes
            for arg in argvec
                input += circ_input(arg)
            end

    elseif head(circ) == :mcopy
        input = length(args(argvec[1]))

    elseif head(circ) == :braid
        input = length(args(argvec[1])) + length(args(argvec[2]))

    elseif head(circ) == :id
        input = length(args(argvec[1]))

    elseif head(circ) == :generator
        input = gate_input(circ)
    end

    return input
end

#function that returns the number of output wires for circuits
function circ_output(circ::Catlab.Theories.FreeCartesianCategory.Hom)::Int

    output = 0
    argvec = args(circ)
    len = length(argvec)

    if head(circ) == :compose
        output = circ_output(argvec[len])

    elseif head(circ) == :otimes
            for arg in argvec
                output += circ_output(arg)
            end

    elseif head(circ) == :mcopy
        output = 2*length(args(argvec[1]))

    elseif head(circ) == :braid
        output = length(args(argvec[1])) + length(args(argvec[2]))

    elseif head(circ) == :id
        output = length(args(argvec[1]))

    elseif head(circ) == :generator
        output = 1
    end

    return output
end

#function that turns circuits to their boolean(vector) functions
#careful! function returned from to_bool_func don't check for domains!
function to_bool_func(circ::Catlab.Theories.FreeCartesianCategory.Hom)::Function

    argvec = args(circ)
    len = length(argvec)

    if head(circ) == :compose
        g_comp = to_bool_func(argvec[1])
        for arg in argvec[2:len]
            g_comp = to_bool_func(arg)∘g_comp
        end
        return g_comp

    elseif head(circ) == :otimes
        g_prod = to_bool_func(argvec[1])
        for arg in argvec[2:len]
            arg_input_size = circ_input(arg)
            *(f₁::Function, f₂::Function) =
                x->vcat(f₁(x[1:length(x) - arg_input_size]),f₂(x[length(x) - arg_input_size + 1:length(x)]))
            g_prod = g_prod*to_bool_func(arg)
        end
        return g_prod

    elseif head(circ) == :mcopy
        g_copy(x) = vcat(x,x)
        return g_copy

    elseif head(circ) == :braid
    copies = length(args(argvec[1]))
        function g_braid(x)
            return vcat(x[copies + 1:len], x[1:copies])
        end
        return g_braid

    elseif head(circ) == :id
    copies = length(args(argvec[1]))
        function g_id(x)
            if length(x) == copies
                return x
            else
                lenx = length(x)
                error("domain $copies not $lenx !")
            end
        end
        return g_id

    elseif head(circ) == :generator
        return gate_to_bool_func(circ)
    end
end

struct Bool_Circuit
    bool_circ::Catlab.Theories.FreeCartesianCategory.Hom
    bool_func::Function
    bool_dom::Int
    bool_cod::Int
    bool_diag
end

function Bool_Circuit(x::Catlab.Theories.FreeCartesianCategory.Hom)::Bool_Circuit
    return Bool_Circuit(x, to_bool_func(x), circ_input(x), circ_output(x), to_diagram(x))
end

#brute force SAT algorithm, loops over all the possible inputs
function brute_SAT(f::Bool_Circuit)
    sat = false
    i = 0
    dom = f.bool_dom
    arr = Bool[]

    if !(f.bool_cod == 1)
        error("circuit codomain needs to be 1!")
    else
        while (!sat)&&(i < 2^dom)
                arr = iszero.(digits(i, base=2, pad=dom))
                sat = f.bool_func(arr)[1]
                i += 1
        end
        return (sat, arr)
    end
end

#TRYME
#demo = (Dup⊗Dup)⋅(NOT⊗σ(B,B)⊗NOT)⋅(AND⊗AND)
#demo_diagram = to_diagram(demo)
#draw(demo_diagram)
#demo_func = to_bool_func(demo)
#demo_func([true, true])
#demo_func([true, false])
#demo_func([false, true])
#demo_func([false, false])
#demo1 = demo⋅NOR
#demo2 = (Dup⊗Dup)⋅(demo⊗demo)⋅(AND⊗AND)
#demo3 = demo2⋅demo1
#demo_ult = (demo3 ⊗ demo3) ⋅ demo3
#demo_ult_circ = Bool_Circuit(demo_ult)
#draw(demo_ult_circ.bool_diag)
#brute_SAT(demo_ult_circ)
#unsatisfiable circuit
#demo_unsat = Dup ⋅ (NOT⊗id(B)) ⋅ NOR
#demo_unsat_circ = Bool_Circuit(demo_unsat)
#draw(demo_unsat_circ.bool_diag)
#brute_SAT(demo_unsat_circ)
#demo_unsat2 = demo_unsat ⋅ demo_unsat ⋅ demo_unsat
#demo_unsat2_circ = Bool_Circuit(demo_unsat2)
#brute_SAT(demo_unsat2_circ)
#demo_unsat_ult = (demo_unsat2⊗demo_unsat2⊗demo_unsat2⊗demo_unsat2)⋅(AND⊗NOR)⋅demo1
#demo_unsat_ult_circ = Bool_Circuit(demo_unsat_ult)
#draw(demo_unsat_ult_circ.bool_diag)
#brute_SAT(demo_unsat_ult_circ)


text:
myDict=Dict{AbstractString, Int}()
myDict["Hi"] = 37
myDict["ho"] = 23
print(barplot(myDict))
myPlot=barplot(["Please","don't","crash","my","friend"], [10,24,30,13,7])
barplot!(myPlot, "and", 5)
print(myPlot)
barplot!(myPlot, ["just", "dont", "!"], [2, 49, 15])
@test_throws DimensionMismatch barplot!(myPlot, ["just", "dont", "!"], [2, 49])
print(myPlot)
print(barplot([5,4,3,2,1], [10,24,30,13,7]))
print(barplot([5,4,3,2,1], [0,0,0,0,0]))
print(barplot([:Please,:dont,:crash,:dude], [10,24,1,13]))
print(barplot([:Please,:dont,:crash,:dude], [10,24,1,13], border=:none))
print(barplot([:Please,:dont,:crash,:dude], [10,24,1,13], border=:solid))
print(barplot([:Please,:dont,:crash,:dude], [10,24,1,13], border=:dashed))
print(barplot([:Please,:dont,:crash,:dude], [1,1,1,1000000], color=:red))
print(barplot([:Please,:dont,:crash,:dude], [10,24,1,13], width=10))
print(barplot([:Please,:dont,:crash,:dude], [10,24,1,13], width=10, margin=0))
print(barplot([:Please,:dont,:crash,:dude], [10,24,1,13], width=10, margin=20))
print(barplot([:Please,:dont,:crash,:dude], [10,24,1,13], width=1))
print(barplot([:Please,:dont,:crash,:dude], [10,24,1,0], width=100))
print(barplot([:Please,:dont,:crash,:dude], [10,24,1,0], title="C'mon man, keep on going!"))
print(barplot([:Please,:dont,:crash,:dude], [10,24,1,0], title="No lab", labels = false))
@test_throws ArgumentError barplot([:Please,:dont,:crash,:dude], [10,-1,1,1])
@test_throws DimensionMismatch barplot([:Please,:dont,:crash,:dude], [10,1,1])
@test_throws ArgumentError barplot([:Please,:dont,:crash,:dude], [10,24,1,0], margin=-1)
print(barplot([:Please,:dont,:crash,:dude], [1.,.7,.1,.6], width=10))

x = [-1.,2, 3, 7]
y = [1.,2, 9, 4]
print(lineplot(x, y))
x = [1.,2, 3, 7]
y = [1.,2, -1, 4]
print(lineplot(x, y))
x = [1,2, 3, 7]
y = [1,2, -1, 4]
@test_throws DimensionMismatch barplot(x, [10,1,1])
@test_throws DimensionMismatch lineplot(x, [10,1,1])
print(lineplot(1:10, 1:10))
print(lineplot(x, y))
@test_throws ArgumentError lineplot(x, y, margin=-1)
print(lineplot(x, y, width=50, height=10))
print(lineplot(x, y, width=100, height=10))
print(lineplot(x, y, width=90, height=40))
print(lineplot(x, y, width=50, height=5, margin = 0))
print(lineplot(x, y, width=10, height=20, margin = 20))
print(lineplot(x, y, width=5, height=5))
print(lineplot(x, y, width=50, height=10, title="Hello world", border=:none))
print(lineplot(x, y, width=50, height=10, title="Hello world", border=:dashed))
print(lineplot(x, y, width=50, height=10, title="Hello world", border=:solid))
print(lineplot(x, y, width=50, height=10, title="Hello world", border=:bold))
print(lineplot(x, y, width=50, height=10, title="Hello world", border=:dotted))
print(lineplot(x, y, width=50, height=10, border=:dotted))
x = [-1.,2, 3, 700000]
y = [1.,2, 9, 4000000]
print(lineplot(x, y))
print(lineplot(x, y, width=5, height=5))
@test_throws ArgumentError scatterplot(x, y, margin=-1)
x = [1.,2, 3, 7]
y = [1.,2, -1, 4]
print(scatterplot(x, y))
x = [1,2, 3, 7]
y = [1,2, -1, 4]
print(scatterplot(x, y))
x = [1.,2, 3, 7]
y = [1,2, -1, 4]
myplot = scatterplot(x)
scatterplot!(myplot, y)
print(myplot)
myplot = scatterplot(x, y)
scatterplot!(myplot, x, y)
print(myplot)
print(scatterplot(x*.001+1.1, y))
print(lineplot(x, y*20+1000))
print(lineplot(x+1000, -y))

myplot = lineplot(collect(1:10))
lineplot!(myplot, collect(1:10))
myplot = lineplot(1:10, collect(1:10))
myplot = lineplot(collect(1:10), 1:10)
myplot = lineplot(1:10, 1:10)
lineplot!(myplot, collect(1:10), 1:10)
lineplot!(myplot, 1:10, collect(1:10))
lineplot!(myplot, 1:10, 1:10)
print(myplot)
print(lineplot([sin, cos]))
print(lineplot(sin))
print(lineplot(sin, 1:.5:10))
print(lineplot(sin, 1:.5:10, labels = false))
print(lineplot(sin, [1., 1.5, 2, 2.5, 3, 3.5, 4]))
print(lineplot(sin, [1, 2, 3, 4]))
print(lineplot(sin, 1, 4))
print(lineplot([sin, cos], 1, 4))
print(lineplot([sin, cos], 1, 4, canvas = BlockCanvas))
print(lineplot([sin, cos], 1, 4, canvas = AsciiCanvas))
print(lineplot([sin, cos], 1, 4, canvas = DotCanvas))

x = [1,2, 4, 7, 8]
y = [1,3, 4, 2, 7]
print(stairs(x, y))
y = [1,3, 4, 2, 7000]
print(stairs(x, y))

#x=rand(100000)
#y=rand(100000)
#@time stairs(x, y)
#@time scatterplot(x, y)
#@time lineplot(x, y)

canvas = BrailleCanvas(40, 10, # number of columns and rows
                       origin_x = 0., origin_y = 0., # position in virtual space
                       width = 1., height = 1.) # size of the virtual space
lines!(canvas, 0., 0., 1., 1., :blue)
points!(canvas, rand(50), rand(50), :red)
points!(canvas, rand(50), rand(50), color = :red)
lines!(canvas, 0., 1., .5, 0., :yellow)
points!(canvas, 1., 1.)
lines!(canvas, [1.,2], [2.,1])

lines!(canvas, 0., 0., .9, 9999., :yellow)
lines!(canvas, 0., 0., 1., 1., color = :blue)
lines!(canvas, .3, .7, 1., 0., :red)
lines!(canvas, 0., 2., .5, 0., :yellow)
print(canvas)
show(STDOUT, canvas)
myPlot = Plot(canvas, title="testtitle")
annotate!(myPlot, :l, ":l auto", :red)
for i in 1:10
  annotate!(myPlot, :l, i, "$i", color=:green)
  annotate!(myPlot, :r, i, "$i", :yellow)
end
print(scatterplot([1],[1]))
@test_throws ArgumentError annotate!(myPlot, :bl, 5, ":l  5", :red)
@test_throws ArgumentError annotate!(myPlot, :d, ":l auto", :red)
annotate!(myPlot, :l, 5, ":l  5", :red)
annotate!(myPlot, :r, 5, "5  :r", color=:red)
annotate!(myPlot, :bl, ":bl", :blue)
annotate!(myPlot, :b, ":b", :green)
annotate!(myPlot, :br, ":br", :magenta)
annotate!(myPlot, :tl, ":tl", :cyan)
annotate!(myPlot, :tr, ":tr")
annotate!(myPlot, :t, ":t", :yellow)
lines!(myPlot, 0., 1., 1., 0., :blue)
lines!(myPlot, 0., 1., 1., 0., color=:blue)
points!(myPlot, rand(10), rand(10))
pixel!(myPlot, 1, 1)
pixel!(myPlot, 1, 1, :green)
pixel!(myPlot, 1, 1, color=:green)

ttl = "title!(plot, text)"
title!(myPlot, ttl)
@test title(myPlot) == ttl

xlab = "xlabel!(plot, text)"
xlabel!(myPlot, xlab)
@test xlabel(myPlot) == xlab

ylab = "ylabel!(plot, text)"
ylabel!(myPlot, ylab)
@test ylabel(myPlot) == ylab

show(STDOUT, myPlot)

x = [1,2, 4, 7, 8]
y = [1,3, 4, 2, 7]
myPlot = stairs(x, y, style=:pre)
print(myPlot)
myPlot = stairs(x, y)
print(myPlot)
stairs!(myPlot, x- .2, y + 1.5)
print(myPlot)

@test_throws ArgumentError lineplot(sin, 1:.5:12, color=:blue, ylim=[-1.,1., 2.])
myPlot = lineplot(sin, 1:.5:12, color=:blue, ylim=[-1.,1.])
print(myPlot)
lineplot!(myPlot, cos, 1:.5:10, color=:red)
print(myPlot)
myPlot = lineplot(sin, 1:.5:12, color=:blue, ylim=[-1,1], xlim=[-1.,5.])
print(myPlot)

x = [1,2, 4, 7, 8]
y = [1,3, 4, 2, 7]
myPlot = stairs(x, y, width = 10, padding = 3)
annotate!(myPlot, :tl, "Hello")
annotate!(myPlot, :t, "how are")
annotate!(myPlot, :tr, "you?")
annotate!(myPlot, :bl, "Hello")
annotate!(myPlot, :b, "how are")
annotate!(myPlot, :br, "you?")
print(myPlot)
lineplot!(myPlot, 1, .5)
print(myPlot)

print(histogram(randn(1000), bins=10, title="Histogram"))
print(histogram(rand(1000), bins=5, title="Histogram"))
print(histogram(rand(1000), title="Histogram"))
print(histogram(rand(1000)*0.001, title="Histogram"))
print(histogram(rand(800) * 10000 - 115000, title="Histogram"))

print(spy(sprand(10,10,.15)))
print(spy(sprand(5,10,.15), width = 5))
print(spy(sprand(5,5,.15), height = 5))
print(spy(sprand(10,10,.15), color=:green))
print(spy(sprand(2000,200,.01), color=:green))
print(spy(sprand(200,2000,.01), color=:green))
print(spy(sprand(1000,10,.01), color=:green))
print(spy(sprand(10,1000,.01), color=:green))
print(spy(full(sprand(10,100,.15))))

x1, y1 = rand(500)*10, rand(500)*10
x2, y2 = rand(1000)*5+1, rand(1000)*5+1
canvas = BrailleCanvas(40, 10,
                       origin_x = 0., origin_y = 0.,
                       width = 10., height = 10.)
points!(canvas, x1, y1, color = :red)
points!(canvas, x1, y1, :red)
points!(canvas, x2, y2, :blue)
show(canvas)
myPlot = densityplot(x1,y1, color = :red)
points!(myPlot, x2, y2, :blue)
show(myPlot)
myPlot = densityplot(randn(1000), randn(1000), color = :blue)
densityplot!(myPlot, randn(1000) + 2, randn(1000) + 2, color = :red)
print(myPlot)

x = rand(100); y = rand(100)
print(scatterplot(x, y, xlim=[minimum(x), maximum(x)], ylim=[minimum(y), maximum(y)]))

x = rand(100) * 1000; y = rand(100) * 1000
print(scatterplot(x, y, xlim=[minimum(x), maximum(x)], ylim=[minimum(y), maximum(y)]))

d = collect(Date(2000,1,1):Date(2000,1,31))
v = collect(linspace(20, 200, 31))
print(lineplot(d,v, height = 5))

miny = -1.2796649117521434e218
maxy = -miny
println(scatterplot([1],[miny],xlim=[1,1],ylim=[miny,maxy],title="Don't you crash on me!"))