Coder Social home page Coder Social logo

merck / algebraicagents.jl Goto Github PK

View Code? Open in Web Editor NEW
20.0 20.0 3.0 2.55 MB

A lightweight framework to enable hierarchical, heterogeneous dynamical systems co-integration. Batteries included!

License: Other

Julia 100.00%
differential-equations dynamical-systems julia julia-language stochastic-processes

algebraicagents.jl's People

Contributors

slwu89 avatar thevolatilebit avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

algebraicagents.jl's Issues

ci (tests, docs, tagbot)

It would be great to automatise docs deployment, add build and code coverage tests, etc. This would apply to our other projects as well.

Status:

  • tests;
  • docs deployment;
  • tagbot;
  • formatter;
  • compat.

mutability of agent structs

Any agent type being made from calling @aagent is mutable, but with Julia versions >= 1.8 now we can specify particular fields as being const, which can help bring performance closer to immutable structs (see https://docs.julialang.org/en/v1/manual/types/#Mutable-Composite-Types). It would be nice to let users to specify fields as const if they like, to improve performance. I'll look into how to make this work with the macros. Alternatively I can also look into how to replicate the functionality with standard functions.

fix agent syncing

Using SciML integration, it may happen that the simulation terminates before all agents have reached the final time point.

Consider

 tspan = (0.0, 6.0) # try various values of `tspan[2]`

function (u,p,t)
    agent = @get_agent p
    y = getobservable(getagent(agent, "../agent_y"), "y")
    return [p.α * y]
end
px == 0.5,)
x0 = [0.1]

function (u,p,t)
    agent = @get_agent p
    x = getobservable(getagent(agent, "../agent_x"), "x")
    return [p.β * x]
end
py == 1.2,)
y0 = [1.0]

agent_x = DiffEqAgent("agent_x", ODEProblem(ẋ,x0,tspan,px), dt=0.00001)
agent_y = DiffEqAgent("agent_y", ODEProblem(ẏ,y0,tspan,py), dt=0.00001)

push_exposed_ports!(agent_x, "x" => 1)
push_exposed_ports!(agent_y, "y" => 1)

joint_system = (agent_x, agent_y; name="joint_system")

sol = AlgebraicAgents.simulate(joint_system)

In general, I propose that we change to implementation of step! to something like

# local step implementation
(_projected_to(a) == t) && _step!(a, t)
@ret ret _projected_to(a)

so that one avoids the errors I made when implementing SciML integration.

Moreover, the implementation of @ret has to be fixed likewise. Note that we want to find the least time point, up to which all agents were projected. Now, _projected_to(a) returns

  • nothing if the agent does not implement its evolution (e.g., wrap of embedded agents),
  • true if we already projected the agent to the final time point (no more calls to _step!,
  • or the time point to which the agent has been projected.

@ret shall return the least time point (or nothing or true). For that calculation, nothing is an idempotent; if all agents return true (or nothing, but at least one is true), then this is true for the entire system, otherwise we take the least number returned by the _projected_to (ingoring possible trues of some agents).

fix `Opera` docs

Apparently I did not update the documentation for Opera properly. For instance, there is a mention of AbstractOperaCall, which has been deprecated.

However the system can work with arbitrary types of interactions. To do so, simply define a new call type that is a subtype of `AbstractOperaCall`. The methods `execute_action!` and `add_instantious!` must be specialized for your new call type. After that, your new interaction type can be used just like any other! To see an example, please check out our tests.

parameterized types using `@aagent`

I was testing if the macros could allow us to use parameterized types for the agents when I noticed that even if there is an error when interpolating the symbols into expressions in define_agent, the name of the new agent type will still be assigned into the current module, it will just have 0 constructor methods.

using AlgebraicAgents

@aagent MyAgent{T<:AbstractString} begin
    myname::T
end

typeof(MyAgent)
methods(MyAgent)
dump(MyAgent)

It might be nice to allow users to define agents as parameterized types for when we still want each agent itself to have a fully concrete type to avoid type instability but also allow flexibility in the particular types, either for dispatch or to integrate with other packages (or for when large numbers of agents are being created programmatically). I will spend some time to think about how to do this, I'm still new to Julia metaprogramming.

saving and loading agent hierarchies

It would be beneficial to incorporate the feature of loading and saving agent hierarchies from and to files in our package. Ideally, an agent hierarchy could be exported into a nested JSON structure. In this structure, specific attributes would be utilized to define the behavioral patterns of the agents.

In alignment with our general approach to package design, we should allow users to customize these load/save methods for their custom agent types.

suggestion for `getobservable`

Currently the indexing operator forwards to getobservable. I've noticed in practical modeling however, we haven't used getobservable very often (and when we do, it's not too much of an annoyance to type out getobservable(agent, keys)). However, in projects, we often have code like inners(depot)["inventory"], or similar lines, appearing throughout the codebase repeatedly. What do you think of changing Base.getindex to instead forward to inners(agent)[keys...]?

change `_step!(agent, time)` to `_step!(agent)`

Now that the call to _step! is implemented as

# `step!` function
if (p = _projected_to(a); !isa(p, Bool) && (p == t))
    _step!(a, t)
end

we could drop the second positional argument (t) to _step!.

Initially, _step! (relative to agent) was expected to perform the evolutionary step if and only if _projected_to(agent) == t. We now check this condition in advance. Moreover, agent may retrieve t using _projected_to.

redundant tutorials

Similar tutorials appear in three different places:

  • in /tutorials folder
  • as tests
  • in documentation

We may remove /tutorials folder after all, and some of the tutorial tests can be done implicitly when documentation is built.

Opera docs/tests

Hi @thevolatilebit! My next plan is to write some tests/documentation for the Opera structure. I'm opening this issue and will close it when I've merged PR(s) that fulfill those goals.

I first had a few questions:

  1. Is it possible to do something like this using the Opera interface: agent A sends information to agent B a deterministic number of time steps from now?
  2. What is a use case for _interact! ?
  3. Similarly, what is the main difference in use cases between schedule_call and schedule?

undefined additional fields

If we make a new agent type with @aagent which has new additional data fields and construct it and print it to the REPL the Base.show method will try to show it with undefined memory which doesn't cause a problem for the program (it keeps running) but results in an error message. We may want to keep this behavior to remind users that they need to manually need to initialize memory because of the way the macros work. I'm just flagging it as potentially worthy of a quick discussion.

MWE:

julia> using AlgebraicAgents
julia> @aagent MyAgent begin
           myname::String
       end

julia> MyAgent("Alice")
agent Alice with uuid 7d15f2a3 of type MyAgent 
   custom properties:Error showing value of type MyAgent:
ERROR: UndefRefError: access to undefined reference
Stacktrace:

how to use `ports_in`?

Hi @thevolatilebit, just curious how ports_in should be used; there appears to be no tests for it. It seems it should link to an exposed port (observable) of another agent.

In a branch here, I was trying to figure it out: https://github.com/slwu89/AlgebraicAgents.jl/blob/c849f0032fe85888c910a3ec87ee0e1627ce0e42/test/integrations/sciml_test.jl#L126 Obviously that test will fail because the DiffEqAgent constructor will call the dynamics function, and there is not yet anything in the ports_in, but I am not sure what is the correct usage to be able to do something like in the test. Also in that branch I had to add a ports_in method for Val{DummyType} otherwise the constructor throws a method error.

TagBot trigger issue

This issue is used to trigger TagBot; feel free to unsubscribe.

If you haven't already, you should update your TagBot.yml to include issue comment triggers.
Please see this post on Discourse for instructions and more details.

If you'd like for me to do this for you, comment TagBot fix on this issue.
I'll open a PR within a few hours, please be patient!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.