Category Archives: Julia

A take on Benders decomposition in JuMP

By: Julia on μβ

Re-posted from: https://matbesancon.github.io/post/2019-05-08-simple-benders/

Last Friday was a great seminar of the Combinatorial Optimization group in
Paris, celebrating the 85th birthday of Jack Edmonds, one of the founding
researchers of combinatorial optimization, with the notable Blossom matching algorithm.

Laurence Wolsey and Ivana Ljubic were both giving talks on applications and
developments in Benders decompositions. It also made me want to refresh my
knowledge of the subject and play a bit with a simple implementation.

Table of Contents

High-level idea

Problem decompositions are used on large-scale optimization problems with a
particular structure. The decomposition turns a compact, hard-to-solve
formulation into an easier one but of great size. In the case of Benders,
great size means a number of constraints growing exponentially
with the size of the input problem. Adding all constraints upfront would be too
costly. Furthermore, in general, only a small fraction of these constraints will be
active in a final solution, the associated algorithm is to generate them incrementally,
re-solve the problem with the new constraint until no relevant constraint can
be found anymore.

We can establish a more general pattern of on-the-fly addition of
information to an optimization problem, which entails two components:

  1. An incrementally-built problem, called Restricted Master Problem (RMP) in decomposition.
  2. An oracle or sub-problem, taking the problem state and building the new required structure (here a new constraint).

Sounds familiar? Benders can be seen as the “dual twin” of the Dantzig-Wolfe
decomposition I had played with in a previous post.

Digging into the structure

Now that we have a general idea of the problem at hand, let’s see the specifics.
Consider a problem such as:
$$ \min_{x,y} f(y) + c^T x $$
s.t. $$ G(y) \in \mathcal{S}$$
$$ A x + D y \geq b $$
$$ x \in \mathbb{R}^{n_1}_{+}, y \in \mathcal{Y} $$

We will not consider the constraints specific to $y$ (the first row) nor the
$y$-component of the objective. The key assumption of Benders is that if the $y$
are fixed, the problem on the $x$ variables is fast to solve.
Lots of heuristics use this idea of “fix-and-optimize” to avoid incorporating
the “hard” variables in the problem, Benders leverages several properties to
bring the idea to exact methods (exact in the sense of proven optimality).

Taking the problem above, we can simplify the structure by abstracting away
(i.e. projecting out) the $x$ part:
$$ \min_{y} f(y) + \phi(y) $$
s.t. $$ G(y) \in \mathcal{S}$$
$$ y \in \mathcal{Y} $$

Where:
$$ \phi(y) = \min_{x} \{c^T x, Ax \geq b – Dy, x \geq 0 \} $$

$\phi(y)$ is a non-smooth function, with $\, dom\ \phi \,$ the feasible domain
of the problem. If you are familiar with bilevel optimization, this could
remind you of the optimal value function used to describe lower-level problems.
We will call $SP$ the sub-problem defined in the function $\phi$.

The essence of Benders is to start from an outer-approximation (overly optimistic)
by replacing $\phi$ with a variable $\eta$ which might be higher than the min value,
and then add cuts which progressively constrain the problem.
The initial outer-approximation is:

$$ \min_{y,\eta} f(y) + \eta $$
s.t. $$ G(y) \in \mathcal{S}$$
$$ y \in \mathcal{Y} $$

Of course since $\eta$ is unconstrained, the problem will start unbounded.
What are valid cuts for this? Let us define the dual of the sub-problem $SP$,
which we will name $DSP$:
$$ \max_{\alpha} (b – Dy)^T \alpha $$
s.t. $$ A^T \alpha \leq c $$
$$ \alpha \geq 0 $$

Given that $\eta \geq min SP$, by duality, $\eta \geq max DSP$.
Furthermore, by strong duality of linear problems, if $\eta = \min \max_{y} DSP$,
it is exactly equal to the minimum of $\phi(y)$ and yields the optimal solution.

One thing to note about the feasible domain of $DSP$, it does not depend on
the value of $y$. This means $z$ feasible for all values of the dual is
equivalent to being feasible for all extreme points and rays of the dual
polyhedron. Each of these can yield a new cut to add to the relaxed problem.
For the sake of conciseness, I will not go into details on the case when
the sub-problem is not feasible for a $y$ solution. Briefly, this is equivalent
to the dual being unbounded, it thus defines an extreme ray which must be cut
out. For more details, you can check these lecture notes.

A JuMP implementation

We will define a simple implementation using JuMP,
a generic optimization modeling library on top of Julia, usable with various
solvers. Since the master and sub-problem resolutions are completely independent,
they can be solved in separated software components, even with different solvers.
To highlight this, we will use SCIP
to solve the master problem and COIN-OR’s Clp
to solve the sub-problem.

We can start by importing the required packages:

using JuMP
import SCIP
import Clp
using LinearAlgebra: dot

Defining and solving dual sub-problems

Let us store static sub-problem data in a structure:

struct SubProblemData
    b::Vector{Float64}
    D::Matrix{Float64}
    A::Matrix{Float64}
    c::Vector{Float64}
end

And the dual sub-problem is entirely contained in another structure:

struct DualSubProblem
    data::SubProblemData
    α::Vector{VariableRef}
    m::Model
end

function DualSubProblem(d::SubProblemData, m::Model)
    α = @variable(m, α[i = 1:size(d.A, 1)] >= 0)
    @constraint(m, dot(d.A, α) .<= d.c)
    return DualSubProblem(d, α, m)
end

The DualSubProblem is constructed from the static data and a JuMP model.
We mentioned that the feasible space of the sub-problem is independent of the
value of $y$, thus we can add the constraint right away. Only to optimize it
do we require the $\hat{y}$ value, which is used to set the objective.
We can then either return a feasibility cut or optimality cut depending on
the solution status of the dual sub-problem:

function JuMP.optimize!(sp::DualSubProblem, yh)
    obj = sp.data.b .- sp.data.D * yh
    @objective(sp.m, Max, dot(obj, sp.α))
    optimize!(sp.m)
    st = termination_status(sp.m)
    if st == MOI.OPTIMAL
        α = JuMP.value.(sp.α)
        return (:OptimalityCut, α)
    elseif st == MOI.DUAL_INFEASIBLE
        return (:FeasibilityCut, α)
    else
        error("DualSubProblem error: status $status")
    end
end

Iterating on the master problem

The main part of the resolution holds here in three steps.

  1. Initialize a master problem with variables $(y,\eta)$
  2. Optimize and pass the $\hat{y}$ value to the sub-problem.
  3. Get back a dual value $\alpha$ from the dual sub-problem
  4. Is the constraint generated by the $\alpha$ value already respected?
  5. If yes, the solution is optimal.
  6. If no, add the corresponding cut to the master problem, return to 2.
function benders_optimize!(m::Model, y::Vector{VariableRef}, sd::SubProblemData, sp_optimizer, f::Union{Function,Type}; eta_bound::Real = -1000.0)
    subproblem = Model(with_optimizer(sp_optimizer))
    dsp = DualSubProblem(sd, subproblem)
    @variable(m, η >= eta_bound)
    @objective(m, Min, f(y) + η)
    optimize!(m)
    st = MOI.get(m, MOI.TerminationStatus())
    # restricted master has a solution or is unbounded
    nopt_cons, nfeas_cons = (0, 0)
    @info "Initial status $st"
    cuts = Tuple{Symbol, Vector{Float64}}[]
    while (st == MOI.DUAL_INFEASIBLE) || (st == MOI.OPTIMAL)
        optimize!(m)
        st = MOI.get(m, MOI.TerminationStatus())
        ŷ = JuMP.value.(y)
        η0 = JuMP.value(η)
        (res, α) = optimize!(dsp, ŷ)
        if res == :OptimalityCut
            @info "Optimality cut found"
            if η0  dot(α, (dsp.data.b - dsp.data.D * ŷ))
                break
            else
                nopt_cons += 1
                @constraint(m, η  dot(α, (dsp.data.b - dsp.data.D * y)))
            end
        else
            @info "Feasibility cut found"
            nfeas_cons += 1
            @constraint(m, 0  dot(α, (dsp.data.b - dsp.data.D * y)))
        end
        push!(cuts, (res, α))
    end
    return (m, y, cuts, nopt_cons, nfeas_cons)
end

Note that we pass the function an already-built model with variable $y$ defined.
This allows for a prior flexible definition of constraints of the type:
$$y \in \mathcal{Y}$$
$$G(y) \in \mathcal{S}$$

Also, we return the $\alpha$ values found by the sub-problems and the number of
cuts of each type. Finally, one “hack” I’m using is to give an arbitrary lower
bound on the $\eta$ value, making it (almost) sure to have a bounded initial
problem and thus a defined initial solution $y$.

We will re-use the small example from the lecture notes above:

function test_data()
    c = [2., 3.]
    A = [1 2;2 -1]
    D = zeros(2, 1) .+ [1, 3]
    b = [3, 4]
    return SimpleBenders.SubProblemData(b, D, A, c)
end

data = test_data()
# objective function on y
f(v) = 2v[1]
# initialize the problem
m = Model(with_optimizer(SCIP.Optimizer))
@variable(m, y[j=1:1] >= 0)
# solve and voilà
(m, y, cuts, nopt_cons, nfeas_cons) = SimpleBenders.benders_optimize!(m, y, data, () -> Clp.Optimizer(LogLevel = 0), f)

The full code is available on
Github, run it, modify it
and don’t hesitate to submit pull requests and issues, I’m sure there are 🙂

Benders is a central pillar for various problems in optimization, research is
still very active to bring it to non-linear convex or non-convex sub-problems
where duality cannot be used. If you liked this post or have questions,
don’t hesitate to react or ping me on Twitter.


A take on Benders decomposition in JuMP

By: Julia on μβ

Re-posted from: https://matbesancon.xyz/post/2019-05-08-simple-benders/

Last Friday was a great seminar of the Combinatorial Optimization group in
Paris, celebrating the 85th birthday of Jack Edmonds, one of the founding
researchers of combinatorial optimization, with the notable Blossom matching algorithm.

Laurence Wolsey and Ivana Ljubic were both giving talks on applications and
developments in Benders decompositions. It also made me want to refresh my
knowledge of the subject and play a bit with a simple implementation.

High-level idea

Problem decompositions are used on large-scale optimization problems with a
particular structure. The decomposition turns a compact, hard-to-solve
formulation into an easier one but of great size. In the case of Benders,
great size means a number of constraints growing exponentially
with the size of the input problem. Adding all constraints upfront would be too
costly. Furthermore, in general, only a small fraction of these constraints will be
active in a final solution, the associated algorithm is to generate them incrementally,
re-solve the problem with the new constraint until no relevant constraint can
be found anymore.

We can establish a more general pattern of on-the-fly addition of
information to an optimization problem, which entails two components:

  1. An incrementally-built problem, called Restricted Master Problem (RMP) in decomposition.
  2. An oracle or sub-problem, taking the problem state and building the new required structure (here a new constraint).

Sounds familiar? Benders can be seen as the “dual twin” of the Dantzig-Wolfe
decomposition I had played with in a previous post.

Digging into the structure

Now that we have a general idea of the problem at hand, let’s see the specifics.
Consider a problem such as:
$$ \min_{x,y} f(y) + c^T x $$
s.t. $$ G(y) \in \mathcal{S}$$
$$ A x + D y \geq b $$
$$ x \in \mathbb{R}^{n_1}_{+}, y \in \mathcal{Y} $$

We will not consider the constraints specific to $y$ (the first row) nor the
$y$-component of the objective. The key assumption of Benders is that if the $y$
are fixed, the problem on the $x$ variables is fast to solve.
Lots of heuristics use this idea of “fix-and-optimize” to avoid incorporating
the “hard” variables in the problem, Benders leverages several properties to
bring the idea to exact methods (exact in the sense of proven optimality).

Taking the problem above, we can simplify the structure by abstracting away
(i.e. projecting out) the $x$ part:
$$ \min_{y} f(y) + \phi(y) $$
s.t. $$ G(y) \in \mathcal{S}$$
$$ y \in \mathcal{Y} $$

Where:
$$ \phi(y) = \min_{x} \{c^T x, Ax \geq b – Dy, x \geq 0 \} $$

$\phi(y)$ is a non-smooth function, with $, dom\ \phi ,$ the feasible domain
of the problem. If you are familiar with bilevel optimization, this could
remind you of the optimal value function used to describe lower-level problems.
We will call $SP$ the sub-problem defined in the function $\phi$.

The essence of Benders is to start from an outer-approximation (overly optimistic)
by replacing $\phi$ with a variable $\eta$ which might be higher than the min value,
and then add cuts which progressively constrain the problem.
The initial outer-approximation is:

$$ \min_{y,\eta} f(y) + \eta $$
s.t. $$ G(y) \in \mathcal{S}$$
$$ y \in \mathcal{Y} $$

Of course since $\eta$ is unconstrained, the problem will start unbounded.
What are valid cuts for this? Let us define the dual of the sub-problem $SP$,
which we will name $DSP$:
$$ \max_{\alpha} (b – Dy)^T \alpha $$
s.t. $$ A^T \alpha \leq c $$
$$ \alpha \geq 0 $$

Given that $\eta \geq min SP$, by duality, $\eta \geq max DSP$.
Furthermore, by strong duality of linear problems, if $\eta = \min \max_{y} DSP$,
it is exactly equal to the minimum of $\phi(y)$ and yields the optimal solution.

One thing to note about the feasible domain of $DSP$, it does not depend on
the value of $y$. This means $z$ feasible for all values of the dual is
equivalent to being feasible for all extreme points and rays of the dual
polyhedron. Each of these can yield a new cut to add to the relaxed problem.
For the sake of conciseness, I will not go into details on the case when
the sub-problem is not feasible for a $y$ solution. Briefly, this is equivalent
to the dual being unbounded, it thus defines an extreme ray which must be cut
out. For more details, you can check these lecture notes.

A JuMP implementation

We will define a simple implementation using JuMP,
a generic optimization modeling library on top of Julia, usable with various
solvers. Since the master and sub-problem resolutions are completely independent,
they can be solved in separated software components, even with different solvers.
To highlight this, we will use SCIP
to solve the master problem and COIN-OR’s Clp
to solve the sub-problem.

We can start by importing the required packages:

using JuMP
import SCIP
import Clp
using LinearAlgebra: dot

Defining and solving dual sub-problems

Let us store static sub-problem data in a structure:

struct SubProblemData
    b::Vector{Float64}
    D::Matrix{Float64}
    A::Matrix{Float64}
    c::Vector{Float64}
end

And the dual sub-problem is entirely contained in another structure:

struct DualSubProblem
    data::SubProblemData
    α::Vector{VariableRef}
    m::Model
end

function DualSubProblem(d::SubProblemData, m::Model)
    α = @variable(m, α[i = 1:size(d.A, 1)] >= 0)
    @constraint(m, dot(d.A, α) .<= d.c)
    return DualSubProblem(d, α, m)
end

The DualSubProblem is constructed from the static data and a JuMP model.
We mentioned that the feasible space of the sub-problem is independent of the
value of $y$, thus we can add the constraint right away. Only to optimize it
do we require the $\hat{y}$ value, which is used to set the objective.
We can then either return a feasibility cut or optimality cut depending on
the solution status of the dual sub-problem:

function JuMP.optimize!(sp::DualSubProblem, yh)
    obj = sp.data.b .- sp.data.D * yh
    @objective(sp.m, Max, dot(obj, sp.α))
    optimize!(sp.m)
    st = termination_status(sp.m)
    if st == MOI.OPTIMAL
        α = JuMP.value.(sp.α)
        return (:OptimalityCut, α)
    elseif st == MOI.DUAL_INFEASIBLE
        return (:FeasibilityCut, α)
    else
        error("DualSubProblem error: status $status")
    end
end

Iterating on the master problem

The main part of the resolution holds here in three steps.

  1. Initialize a master problem with variables $(y,\eta)$
  2. Optimize and pass the $\hat{y}$ value to the sub-problem.
  3. Get back a dual value $\alpha$ from the dual sub-problem
  4. Is the constraint generated by the $\alpha$ value already respected?
  • If yes, the solution is optimal.
  • If no, add the corresponding cut to the master problem, return to 2.
function benders_optimize!(m::Model, y::Vector{VariableRef}, sd::SubProblemData, sp_optimizer, f::Union{Function,Type}; eta_bound::Real = -1000.0)
    subproblem = Model(with_optimizer(sp_optimizer))
    dsp = DualSubProblem(sd, subproblem)
    @variable(m, η >= eta_bound)
    @objective(m, Min, f(y) + η)
    optimize!(m)
    st = MOI.get(m, MOI.TerminationStatus())
    # restricted master has a solution or is unbounded
    nopt_cons, nfeas_cons = (0, 0)
    @info "Initial status $st"
    cuts = Tuple{Symbol, Vector{Float64}}[]
    while (st == MOI.DUAL_INFEASIBLE) || (st == MOI.OPTIMAL)
        optimize!(m)
        st = MOI.get(m, MOI.TerminationStatus())
        ŷ = JuMP.value.(y)
        η0 = JuMP.value(η)
        (res, α) = optimize!(dsp, ŷ)
        if res == :OptimalityCut
            @info "Optimality cut found"
            if η0  dot(α, (dsp.data.b - dsp.data.D * ŷ))
                break
            else
                nopt_cons += 1
                @constraint(m, η  dot(α, (dsp.data.b - dsp.data.D * y)))
            end
        else
            @info "Feasibility cut found"
            nfeas_cons += 1
            @constraint(m, 0  dot(α, (dsp.data.b - dsp.data.D * y)))
        end
        push!(cuts, (res, α))
    end
    return (m, y, cuts, nopt_cons, nfeas_cons)
end

Note that we pass the function an already-built model with variable $y$ defined.
This allows for a prior flexible definition of constraints of the type:
$$y \in \mathcal{Y}$$
$$G(y) \in \mathcal{S}$$

Also, we return the $\alpha$ values found by the sub-problems and the number of
cuts of each type. Finally, one “hack” I’m using is to give an arbitrary lower
bound on the $\eta$ value, making it (almost) sure to have a bounded initial
problem and thus a defined initial solution $y$.

We will re-use the small example from the lecture notes above:

function test_data()
    c = [2., 3.]
    A = [1 2;2 -1]
    D = zeros(2, 1) .+ [1, 3]
    b = [3, 4]
    return SimpleBenders.SubProblemData(b, D, A, c)
end

data = test_data()
# objective function on y
f(v) = 2v[1]
# initialize the problem
m = Model(with_optimizer(SCIP.Optimizer))
@variable(m, y[j=1:1] >= 0)
# solve and voilà
(m, y, cuts, nopt_cons, nfeas_cons) = SimpleBenders.benders_optimize!(m, y, data, () -> Clp.Optimizer(LogLevel = 0), f)

The full code is available on
Github, run it, modify it
and don’t hesitate to submit pull requests and issues, I’m sure there are 🙂

Benders is a central pillar for various problems in optimization, research is
still very active to bring it to non-linear convex or non-convex sub-problems
where duality cannot be used. If you liked this post or have questions,
don’t hesitate to react or ping me on Twitter.


Newsletter May 2019

Q: Is there an easy-to-find, easy-to-use searchable website where I can find a comprehensive inventory of Julia packages and Julia package documentation?

A: Pkg.julialang.org now includes improved Julia package documentation and search powered by JuliaTeam. You can now search Julia package names, tags, code and documentation to find the best Julia packages that fit your requirements.

Please contact us to learn how JuliaTeam can provide this same functionality within your enterprise development environment, including your own private Julia packages and more.

Stefan Karpinski explains in JuliaTeam
Vision
:

Documentation. Providing a single place to find all documentation for the Julia packages that you use. This service offers a single consistent place and way to host and publish package documentation. It also makes cross-linking docs between packages easy since they all live in the same place. Developers shouldn’t ever have to set up or think about the how of documentation hosting‚ they should just need to follow standard conventions for inline docs and then push their code. The docs service does the rest: cross-linked, searchable (see the next bullet point) docs are generated automatically.

Search. Currently search and discovery of packages is a serious pain point in the Julia ecosystem. JuliaTeam will provide integrated search of documentation and code for all packages. This will let you find the package that does what you need, whether it’s a public open source package or a private package that your organization uses‚ they’ll all be searchable in a single place.

Los Alamos National Laboratory Uses Julia to Predict Power Outages Caused by Extreme Events: Los Alamos National Laboratory used Julia to develop free, open source package – PowerModelsMLD.jl – that simulates the impact of disasters and predicts how the electric grid will be affected. This software can be used to allocate evacuation, rescue, relief and recovery resources.

Naval Postgraduate School Researchers Use Julia for Next Generation Climate Model: Naval Postgraduate School Professors Frank Giraldo, Lucas Wilcox and Jeremy Kozdon use Julia to create a new Earth Systems Model that is “poised to be the most accurate climate modeling system to date.‚”

Julia: The Programming Language Machine Learning Needs

The discussion around the future of machine learning continues to be atopic of interest at conferences and on Twitter. As workloads become diverse and complex, and generalize from the neural networks of today to Differentiable Programming, the question about programmability naturally arises. We have published several blogs on the topic (What is Differentiable Programming and Reinforcement Learning vs. Differentiable Programming).

Facebook AI’s Soumith Chintala has this to say about Julia:

JuliaAcademy: Julia Computing’s training offerings continue to expand. JuliaAcademy is the Julia Computing training platform for 3 types of learning: self-directed, online instructor-led and in-person onsite training.

Course Title and Description Date (11 am – 3 pm EDT) Cost Register
Introduction to Machine Learning and Artificial Intelligence in Julia May 2-3 $500 Register
Parallel Computing in Julia May 8-9 $500 Register

JuliaAcademy courses include: Intro to Julia, Machine Learning and Artificial Intelligence in Julia, Parallel Computing in Julia, Deep Learning with Flux, Optimization with JuMP and Machine Learning with Knet.

JuliaAcademy provides:

  1. Self-directed training – all online, learn at your own pace

  2. Instructor-led online training – live two-day courses taught by Julia Computing instructors

  3. In-person training – contact us at [email protected] to schedule customized in-person training for your organization

Register now for instructor-led online courses. All courses include 8 hours of instruction: 4 hours per day for two consecutive days. Currently scheduled courses are from 11 am – 3 pm Eastern Daylight Time (US).

Julia & Flux – Modernizing Machine Learning: Computação Brasil published Julia e Flux: Modernizando o Aprendizado de Máquina by Dhairya Gandhi, Mike Innes, Elliot Saba, Keno Fischer and Viral Shah.

Algorithms for Optimization (Using Julia): Mykel Kochenderfer and Tim Wheeler have published Algorithms for Optimization which uses Julia to provide a comprehensive introduction to optimization with a focus on practical algorithms.

Julia Programming for Operations Research: Changhyun Kwon from the University of South Florida has published Julia Programming for Operations Research.

JuliaCon 2019: JuliaCon 2019 will be
held July 22-26 at the University of Maryland, Baltimore. Early Bird
Ticket Sales
end May 5.

JuliaCon is looking for sponsors
and university partners in diversity. Sponsorship is available at
several levels and benefits include prominent mention and logo placement
at JuliaCon and in JuliaCon conference materials and Website, an
opportunity to present to JuliaCon participants, presentation space
during the conference and registration for JuliaCon attendees. Past
JuliaCon sponsors include the Alfred P. Sloan Foundation, Microsoft,
Maven, Invenia, Julia Computing, Capital One, Gordon and Betty Moore
Foundation, Gambit Research, Tangent Works, Amazon, Alan Turing
Institute, Jeffrey Sarnoff, EVN and Conning.

Julia and Julia Computing in the News

  • Analytics
    India
    :
    10 Fastest Growing Programming Languages That Employers Demand In
    2019

  • Analytics
    India
    :
    Annual Survey On Data Science Recruitment In India: 2019

  • Apple: What Are the Biggest Software Challenges in Machine Learning?

  • Computação Brasil: Julia e Flux: Modernizando o Aprendizado de Máquina

  • Computing: The Top 10 Most In-Demand IT Skills for 2019

  • DevClass: Julia 101 – The Upstart Language with a Lot to Offer

  • Edgy: Why Julia is the Programming Language set to Dominate our Future

  • EFinancialCareers: Should You Learn to Program in Julia to Get Ahead in Finance?

  • Forbes: How Are Computer Programming Languages Created?

  • Forbes: What Will Machine Learning Look Like In Twenty Years?

  • HPCWire: Julia and NASA Help the Nature Conservancy Save the Planet with Circuitscape

  • LeiPhone: 芯片行业30年资深人士:AI为何是高性能计算史上 “最大的变革推动者”

  • MoneyControl: Algo Trading: Here Are Five Steps to Set Up Your Own Algorithm

  • ODSC:
    Reinforcement Learning vs. Differentiable Programming

  • PC Revue: Päť Predikcií: Takto Bude Vyzerať Strojové Učenie o 20 Rokov

  • Sohu:十大应用在数学的计算机语言

Julia Blog Posts

Upcoming Julia Events

Recent Julia Events

Julia Meetup Groups: There are 35 Julia Meetup groups worldwide with 8,092 members. If there’s a Julia Meetup group in your area, we hope you will consider joining, participating and helping to organize events. If there isn’t, we hope you will consider starting one.

Julia Jobs, Fellowships and Internships

Do you work at or know of an organization looking to hire Julia
programmers as staff, research fellows or interns? Would your employer
be interested in hiring interns to work on open source packages that are
useful to their business? Help us connect members of our community to
great opportunities by sending us an
email, and we’ll get the word out.

There are more than 300 Julia jobs currently listed on
Indeed.com, including jobs at Accenture,
Airbus, Amazon, AstraZeneca, Barnes & Noble, BlackRock, Capital One,
Charles River Analytics, Citigroup, Comcast, Cooper Tire & Rubber,
Disney, Facebook, Gallup, Genentech, General Electric, Google, Huawei,
Johnson & Johnson, Match, McKinsey, NBCUniversal, Nielsen, OKCupid,
Oracle, Pandora, Peapod, Pfizer, Raytheon, Zillow, Brown, Emory,
Harvard, Johns Hopkins, Massachusetts General Hospital, Penn State, UC
Davis, University of Chicago, University of Virginia, Argonne National
Laboratory, Lawrence Berkeley National Laboratory, Los Alamos National
Laboratory, National Renewable Energy Laboratory, Oak Ridge National
Laboratory, State of Wisconsin and many more.

Contact Us: Please contact us if
you wish to:

  • Purchase or obtain license information for Julia products such as
    JuliaAcademy, JuliaTeam, or JuliaPro

  • Obtain pricing for Julia consulting projects for your organization

  • Schedule Julia training for your organization

  • Share information about exciting new Julia case studies or use cases

  • Spread the word about an upcoming conference, workshop, training,
    hackathon, meetup, talk or presentation involving Julia

  • Partner with Julia Computing to organize a Julia meetup, conference,
    workshop, training, hackathon, talk or presentation involving Julia

  • Submit a Julia internship, fellowship or job posting

About Julia and Julia Computing

Julia is the fastest high performance open
source computing language for data, analytics, algorithmic trading,
machine learning, artificial intelligence, and other scientific and
numeric computing applications. Julia solves the two language problem by
combining the ease of use of Python and R with the speed of C++. Julia
provides parallel computing capabilities out of the box and unlimited
scalability with minimal effort. Julia has been downloaded more than 8.4
million times and is used at more than 1,500 universities. Julia
co-creators are the winners of the 2019 James H. Wilkinson Prize for
Numerical Software. Julia has run at
petascale
on
650,000 cores with 1.3 million threads to analyze over 56 terabytes of
data using Cori, one of the ten largest and most powerful supercomputers
in the world.

Julia Computing was founded in 2015
by all the creators of Julia to develop products and provide
professional services to businesses and researchers using Julia.