Git Product home page Git Product logo

mccormick.jl's Introduction

McCormick.jl

A Forward McCormick Operator Library

PSOR Lab Build Status
Build Status codecov
Documentation Persistent DOI
DOI

McCormick.jl is a component package in the EAGO ecosystem and is reexported by EAGO.jl. It contains a library of forward McCormick operators (both nonsmooth and differentiable). Documentation for this is included in the EAGO.jl package and additional usage examples are included in EAGO-notebooks as Jupyter Notebooks.

McCormick Operator Variants

Each McCormick object is associated with a parameter T <: RelaxTag which is either NS for nonsmooth relaxations (Mitsos2009, Scott2011), MV for multivariate relaxations (Tsoukalas2014, Najman2017), or Diff for differentiable relaxations (Khan2016, Khan2018, Khan2019). Conversion between NS, MV, and Diff relax tags are not currently supported. Convex and concave envelopes are used to compute relaxations of univariate functions.

Supported Operators

In addition to supporting the implicit relaxation routines of Stuber 2015, this package supports the computation of convex/concave relaxations (and associated subgradients) for expressions containing the following operations:

Common Algebraic Expressions: inv, log, log2, log10, exp, exp2, exp10, sqrt, +, -, ^, min, max, /, *, abs, step, sign, deg2rad, rad2deg, abs2, cbrt, fma, xlogx, arh, xexpax

Trigonometric Functions: sin, cos, tan, asin, acos, atan, sec, csc, cot, asec, acsc, acot, sind, cosd, tand, asind, acosd, atand, secd, cscd, cotd, asecd, acscd, acotd, sinpi, cospi

Hyperbolic Functions: sinh, cosh, tanh, asinh, acosh, atanh, sech, csch, coth, acsch, acoth

Special Functions: erf, erfc, erfcinv, erfc

Activation Functions: relu, leaky_relu, param_relu, sigmoid, bisigmoid, softsign, softplus, maxtanh, pentanh, gelu, elu, selu, swish1

Bound Specification Functions: positive, negative, lower_bnd, upper_bnd, bnd

Other Functions: one, zero, intersect, real, dist, eps, <, <=, ==

Differentiable relaxations (Diff <: RelaxTag) are supported for the functions given in Khan2016, Khan2018, Khan2019. However, differentiable relaxations for other nonsmooth terms listed above have yet to be developed and as such have been omitted.

Bounding a Univariate Function

In order to bound a function using a McCormick relaxation, you first construct a McCormick object (x::MC) that bounds the input variables, and then you pass these variables to the desired function.

In the example below, convex/concave relaxations of the function

$$f(x) = x (x - 5) \sin(x)$$

are calculated at $x = 2$ on the interval $X = [1, 4]$.

using McCormick

# Create MC object for x = 2.0 on [1.0, 4.0] for relaxing
# a function f(x) on the interval Intv

f(x) = x*(x - 5.0)*sin(x)

x = 2.0                          # Value of independent variable x
Intv = Interval(1.0, 4.0)        # Define interval to relax over
                                 # Note that McCormick.jl reexports IntervalArithmetic.jl
                                 # and StaticArrays. So no using statement for these is
                                 # necessary.
# Create McCormick object
xMC = MC{1,NS}(x, Intv, 1)

fMC = f(xMC)             # Relax the function

cv = fMC.cv              # Convex relaxation
cc = fMC.cc              # Concave relaxation
cvgrad = fMC.cv_grad     # Subgradient/gradient of convex relaxation
ccgrad = fMC.cc_grad     # Subgradient/gradient of concave relaxation
Iv = fMC.Intv            # Retrieve interval bounds of f(x) on Intv

Plotting the results, we can easily visualize the convex and concave relaxations, interval bounds, and affine bounds constructed using the subgradient at the middle of $X$.

Bounding a Multivariate Function

This can readily be extended to multivariate functions, for example:

$$ \begin{aligned} & f(x, y) = \big(4 - 2.1 x^{2} + \frac{x^{4}}{6} \big) x^{2} + x y + (-4 + 4 y^{2}) y^{2}\\ & X = [-2, 0]\\ & Y = [-0.5, 0.5] \end{aligned} $$

using McCormick

# Define function
f(x, y) = (4.0 - 2.1*x^2 + (x^4)/6.0)*x^2 + x*y + (-4.0 + 4.0*y^2)*y^2

# Define intervals for independent variables
n = 30
X = Interval{Float64}(-2, 0)
Y = Interval{Float64}(-0.5, 0.5)
xrange = range(X.lo, stop=X.hi, length=n)
yrange = range(Y.lo, stop=Y.hi, length=n)

# Calculate differentiable McCormick relaxation
for (i,x) in enumerate(xrange)
    for (j,y) in enumerate(yrange)
        z = f(x, y)                 # Calculate function values
        xMC = MC{1,Diff}(x, X, 1)   # Differentiable relaxation for x
        yMC = MC{1,Diff}(y, Y, 2)   # Differentiable relaxation for y
        fMC = f(xMC, yMC)           # Relax the function
        cv = fMC.cv                 # Convex relaxation
        cc = fMC.cc                 # Concave relaxation
    end
end

Citing McCormick.jl

McCormick.jl is a component of the EAGO.jl ecosystem. Please cite the following paper when using McCormick.jl:

M. E. Wilhelm & M. D. Stuber (2022) EAGO.jl: easy advanced global optimization in Julia,
Optimization Methods and Software, 37:2, 425-450, DOI: 10.1080/10556788.2020.1786566

Unit Testing Note

While McCormick.jl generally supports Julia 1.1+, some functions may return an error for Julia versions less than 1.3. In particular, cbrt will result in a StackOverflow when called. McCormick is unit tested using Julia versions 1.3 and beyond.

References

  • Khan KA, Watson HAJ, Barton PI (2017). Differentiable McCormick relaxations. Journal of Global Optimization, 67(4):687-729.
  • Khan KA, Wilhelm ME, Stuber MD, Cao H, Watson HAJ, Barton PI (2018). Corrections to: Differentiable McCormick relaxations. Journal of Global Optimization, 70(3):705-706.
  • Khan KA (2019). Whitney differentiability of optimal-value functions for bound-constrained convex programming problems. Optimization 68(2-3): 691-711
  • Mitsos A, Chachuat B, and Barton PI. (2009). McCormick-based relaxations of algorithms. SIAM Journal on Optimization, 20(2):573–601.
  • Najman J, Bongratz D, Tsoukalas A, and Mitsos A (2017). Erratum to: Multivariate McCormick relaxations. Journal of Global Optimization, 68:219-225.
  • Najman, J, Bongartz, D., and Mitsos A (2019). "Relaxations of thermodynamic property and costing models in process engineering." Computers & Chemical Engineering, 130, 106571.
  • Scott JK, Stuber MD, and Barton PI. (2011). Generalized McCormick relaxations. Journal of Global Optimization, 51(4):569–606.
  • Stuber MD, Scott JK, Barton PI (2015). Convex and concave relaxations of implicit functions. Optim. Methods Softw. 30(3), 424–460
  • Tsoukalas A and Mitsos A (2014). Multivariate McCormick Relaxations. Journal of Global Optimization, 59:633–662.
  • Wechsung A, Scott JK, Watson HAJ, and Barton PI. (2015). Reverse propagation of McCormick relaxations. Journal of Global Optimization 63(1):1-36.

mccormick.jl's People

Contributors

dimitrialston avatar matthewstuber avatar mewilhel avatar mlubin avatar rxgottlieb avatar

Stargazers

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

Watchers

 avatar  avatar  avatar

mccormick.jl's Issues

Support for alternative Interval types

We've currently bound the interval domain calculations to the Interval{Float64} type in IntervalArithmetic.jl. Other inclusion arithmetic can be used (AffineArithmetic, etc.) So adding support for this would be useful.

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!

Domain violations for sec, csc, cot on valid domains.

These functions are defined as composites using the inverse (e.g. cot(x::MC)= inv(tan(x))) which results in domain violations on intervals tighter than Interval(0, pi).

The fix here is to add definitions for sec, csc, cot, asec, acsc, acot that aren't defined as composites. Basically, check for domain violations and return nan(x) if this is the case. Otherwise, compute the envelope. This would also require explicit definitions of these functions in IntervalArithmetic.jl since cot(x::Interval) has the same issue.

exp(x::MC) contains NaNs when x is degenerate

I am a summer undergraduate research assistant working with Dr. Kamil Khan. We found that the concave relaxation of exp(x::MC) seems to be computed as NaN when x is degenerate. Presumably this is because of division by 0 in the secant formula in the concave relaxation of exp.

Example (using Julia v1.9.2 and McCormick.jl v0.13.4):

julia> using McCormick

julia> x = MC{1,NS}(2.0)
MC{1, NS}(2.0, 2.0, [2, 2], [0.0], [0.0], true)

julia> exp(x)
MC{1, NS}(7.38905609893065, NaN, [7.38905, 7.38906], [0.0], [NaN], true)

julia> exp(x).cc
NaN

Request: MC constructor without known subgradients

Hi all,

It'd be great to have a constructor for MC which takes just the cv, cc, and Intv arguments, for situations where we don't know or care about subgradients. This specific constructor would be useful when playing around with e.g. the various McCormick composition rules, and the Scott-Barton relaxations of ODE solutions, and when introducing these concepts to new students.

Of course we can already "roll our own" constructor based on MC's default constructor, but this requires a user to know what an SVector is and how to use it, and to know what a subgradient is.

Kamil

Add tight trilinear form

  • Add the basic trilinear relaxation
  • Compute and plot relaxation cases as a sanity check.
  • Check performance (no allocations in benchmarking)
  • Add unit tests for trilinear
  • Default to the trilinear relaxation for *(x,y,z)
  • Add methods for *(x, y, z, a, b, c) and so on which use use the trilinear form rather than *(x, *(y, *(z, *(a, *(b, c)))))

Correctly Rounding McCormick operator mode

  • Introduce a NSSafe McCormick operator mode, which correctly rounds convex and concave relaxations.
  • Introduce a utility function that takes a box P, a point p, a function, and an input McCormick relaxations then outer rounds cv and cc further to ensure that the subgradients are valid in the presence of rounding error.

Drop StaticArray Dependency for NTuples?

There now isn't any overhead associated with broadcasting addition, scalar multiplication of tuples, and so on. We could potentially reformulate the MC definition to drop the StaticArray dependency.

Add additional activation functions

  • tanhshrink(x) = x - tanh(x) (concavoconvex)
  • relu6(x) = min(max(0, x), 6) (convexoconcave)
  • mish(x) = x * tanh(softplus(x)) (mixed convexity)
  • lisht(x) = x * tanh(x)
  • hardtanh(x) = max(-1, min(1, x)) (softmax)

Julia exited after using McCormick

Julia version 1.1.1
McCormick version 0.5.2
Reproduce:
add McCormick, using McCormick, then Julia exited with the following error message.

Please submit a bug report with steps to reproduce this fault, and any error messages that follow (in their entirety). Thanks.
Exception: EXCEPTION_ACCESS_VIOLATION at 0x6b64b09f -- jl_compile_linfo at /home/Administrator/buildbot/worker/package_win64/build/src/home/Administrator/buildbot/worker/package_win64/build/src\codegen.cpp:1176
in expression starting at no file:0
jl_compile_linfo at /home/Administrator/buildbot/worker/package_win64/build/src/home/Administrator/buildbot/worker/package_win64/build/src\codegen.cpp:1176
emit_invoke at /home/Administrator/buildbot/worker/package_win64/build/src/home/Administrator/buildbot/worker/package_win64/build/src\codegen.cpp:3145
emit_expr at /home/Administrator/buildbot/worker/package_win64/build/src/home/Administrator/buildbot/worker/package_win64/build/src\codegen.cpp:3948
emit_ssaval_assign at /home/Administrator/buildbot/worker/package_win64/build/src/home/Administrator/buildbot/worker/package_win64/build/src\codegen.cpp:3662
emit_stmtpos at /home/Administrator/buildbot/worker/package_win64/build/src/home/Administrator/buildbot/worker/package_win64/build/src\codegen.cpp:3854 [inlined]
emit_function at /home/Administrator/buildbot/worker/package_win64/build/src/home/Administrator/buildbot/worker/package_win64/build/src\codegen.cpp:6277
jl_compile_linfo at /home/Administrator/buildbot/worker/package_win64/build/src/home/Administrator/buildbot/worker/package_win64/build/src\codegen.cpp:1144
emit_invoke at /home/Administrator/buildbot/worker/package_win64/build/src/home/Administrator/buildbot/worker/package_win64/build/src\codegen.cpp:3145
emit_expr at /home/Administrator/buildbot/worker/package_win64/build/src/home/Administrator/buildbot/worker/package_win64/build/src\codegen.cpp:3948
emit_ssaval_assign at /home/Administrator/buildbot/worker/package_win64/build/src/home/Administrator/buildbot/worker/package_win64/build/src\codegen.cpp:3662
emit_stmtpos at /home/Administrator/buildbot/worker/package_win64/build/src/home/Administrator/buildbot/worker/package_win64/build/src\codegen.cpp:3854 [inlined]
emit_function at /home/Administrator/buildbot/worker/package_win64/build/src/home/Administrator/buildbot/worker/package_win64/build/src\codegen.cpp:6277
jl_compile_linfo at /home/Administrator/buildbot/worker/package_win64/build/src/home/Administrator/buildbot/worker/package_win64/build/src\codegen.cpp:1144
emit_invoke at /home/Administrator/buildbot/worker/package_win64/build/src/home/Administrator/buildbot/worker/package_win64/build/src\codegen.cpp:3145
emit_expr at /home/Administrator/buildbot/worker/package_win64/build/src/home/Administrator/buildbot/worker/package_win64/build/src\codegen.cpp:3948
emit_ssaval_assign at /home/Administrator/buildbot/worker/package_win64/build/src/home/Administrator/buildbot/worker/package_win64/build/src\codegen.cpp:3662
emit_stmtpos at /home/Administrator/buildbot/worker/package_win64/build/src/home/Administrator/buildbot/worker/package_win64/build/src\codegen.cpp:3854 [inlined]
emit_function at /home/Administrator/buildbot/worker/package_win64/build/src/home/Administrator/buildbot/worker/package_win64/build/src\codegen.cpp:6277
jl_compile_linfo at /home/Administrator/buildbot/worker/package_win64/build/src/home/Administrator/buildbot/worker/package_win64/build/src\codegen.cpp:1144
emit_invoke at /home/Administrator/buildbot/worker/package_win64/build/src/home/Administrator/buildbot/worker/package_win64/build/src\codegen.cpp:3145
emit_expr at /home/Administrator/buildbot/worker/package_win64/build/src/home/Administrator/buildbot/worker/package_win64/build/src\codegen.cpp:3948
emit_ssaval_assign at /home/Administrator/buildbot/worker/package_win64/build/src/home/Administrator/buildbot/worker/package_win64/build/src\codegen.cpp:3662
emit_stmtpos at /home/Administrator/buildbot/worker/package_win64/build/src/home/Administrator/buildbot/worker/package_win64/build/src\codegen.cpp:3854 [inlined]
emit_function at /home/Administrator/buildbot/worker/package_win64/build/src/home/Administrator/buildbot/worker/package_win64/build/src\codegen.cpp:6277
jl_compile_linfo at /home/Administrator/buildbot/worker/package_win64/build/src/home/Administrator/buildbot/worker/package_win64/build/src\codegen.cpp:1144
emit_invoke at /home/Administrator/buildbot/worker/package_win64/build/src/home/Administrator/buildbot/worker/package_win64/build/src\codegen.cpp:3145
emit_expr at /home/Administrator/buildbot/worker/package_win64/build/src/home/Administrator/buildbot/worker/package_win64/build/src\codegen.cpp:3948
emit_ssaval_assign at /home/Administrator/buildbot/worker/package_win64/build/src/home/Administrator/buildbot/worker/package_win64/build/src\codegen.cpp:3662
emit_stmtpos at /home/Administrator/buildbot/worker/package_win64/build/src/home/Administrator/buildbot/worker/package_win64/build/src\codegen.cpp:3854 [inlined]
emit_function at /home/Administrator/buildbot/worker/package_win64/build/src/home/Administrator/buildbot/worker/package_win64/build/src\codegen.cpp:6277
jl_compile_linfo at /home/Administrator/buildbot/worker/package_win64/build/src/home/Administrator/buildbot/worker/package_win64/build/src\codegen.cpp:1144
jl_fptr_trampoline at /home/Administrator/buildbot/worker/package_win64/build/src/home/Administrator/buildbot/worker/package_win64/build/src\gf.c:1807
jl_apply_generic at /home/Administrator/buildbot/worker/package_win64/build/src/home/Administrator/buildbot/worker/package_win64/build/src\gf.c:2197
wsitem at C:\Users\caohu\.julia\packages\Atom\9h5Up\src\workspace.jl:22
wsitem at C:\Users\caohu\.julia\packages\Atom\9h5Up\src\workspace.jl:19
jl_fptr_trampoline at /home/Administrator/buildbot/worker/package_win64/build/src/home/Administrator/buildbot/worker/package_win64/build/src\gf.c:1842
jl_apply_generic at /home/Administrator/buildbot/worker/package_win64/build/src/home/Administrator/buildbot/worker/package_win64/build/src\gf.c:2197
#255 at C:\Users\caohu\.julia\packages\Atom\9h5Up\src\workspace.jl:8
_collect at .\generator.jl:47
collect_similar at .\array.jl:548 [inlined]
map at .\abstractarray.jl:2018 [inlined]
workspace at C:\Users\caohu\.julia\packages\Atom\9h5Up\src\workspace.jl:8
jl_fptr_trampoline at /home/Administrator/buildbot/worker/package_win64/build/src/home/Administrator/buildbot/worker/package_win64/build/src\gf.c:1842
jl_apply_generic at /home/Administrator/buildbot/worker/package_win64/build/src/home/Administrator/buildbot/worker/package_win64/build/src\gf.c:2197
handlemsg at C:\Users\caohu\.julia\packages\Atom\9h5Up\src\comm.jl:169
unknown function (ip: 000000001E4CF4B3)
jl_apply_generic at /home/Administrator/buildbot/worker/package_win64/build/src/home/Administrator/buildbot/worker/package_win64/build/src\gf.c:2197
jl_apply at /home/Administrator/buildbot/worker/package_win64/build/src/home/Administrator/buildbot/worker/package_win64/build/src\julia.h:1571 [inlined]
jl_f__apply at /home/Administrator/buildbot/worker/package_win64/build/src/home/Administrator/buildbot/worker/package_win64/build/src\builtins.c:556
#31 at .\task.jl:259
unknown function (ip: 000000001E563E7A)
jl_apply_generic at /home/Administrator/buildbot/worker/package_win64/build/src/home/Administrator/buildbot/worker/package_win64/build/src\gf.c:2197
jl_apply at /home/Administrator/buildbot/worker/package_win64/build/src/home/Administrator/buildbot/worker/package_win64/build/src\julia.h:1571 [inlined]
start_task at /home/Administrator/buildbot/worker/package_win64/build/src/home/Administrator/buildbot/worker/package_win64/build/src\task.c:572
Allocations: 58283845 (Pool: 58265554; Big: 18291); GC: 130

Issue with the subtangent of differentiable McCormick relaxations

Observed an incorrect subtangent of differentiable McCormick relaxations:

MWE

Code to reproduce this figure:

using McCormick, DataFrames, IntervalArithmetic

f(x,p) = (x-p)^2

# create a data frame to store output data
df = DataFrame(x = Float64[], y = Float64[], cv1 = Float64[],
               cc1 = Float64[],  l1 = Float64[],
               u1 = Float64[], scv1 = Float64[], scc1 = Float64[])

# generate relaxations
MCOption = Diff # NS
p = 0.1
p_I = Interval(0.0,2.0)
p_mc = MC{2,MCOption}(p,p_I,2)

X = Interval(0.0,3.0)
x_range = range(X.lo,stop=X.hi,length=100)
for x in x_range
    y = f(x,p)
    x_mc = MC{2,MCOption}(x,X,1)
    f_mc = f(x_mc, p_mc)
    save_tuple = (x, y, f_mc.cv, f_mc.cc,
                   lo(f_mc.Intv), hi(f_mc.Intv),
                   f_mc.cv_grad[1], f_mc.cc_grad[1])
    push!(df, save_tuple)
end

# generate subtangent lines at posi
df2 = DataFrame(x = Float64[], tan_cv = Float64[], tan_cc = Float64[])
posi = 40
x_range2 = range(x_range[posi-10], stop=x_range[posi+10], length=20)
for x in x_range2
    tanLo = df.scv1[posi]*(x - df.x[posi]) + df.cv1[posi]
    tanHi = df.scc1[posi]*(x - df.x[posi]) + df.cc1[posi]
    push!(df2, (x, tanLo, tanHi))
end

using Plots
pyplot()
data_mc = [df.y,df.cv1,df.cc1]
plt = Plots.plot(x_range, data_mc, title="McCormick Relaxation")
plt = Plots.plot!(x_range2, df2.tan_cv, linewidth=3, label = "subtangents")
plt = Plots.plot!(x_range2, df2.tan_cc, linewidth=3, label = "supertangents")
display(plt)

Relevant environment information:
versioninfo()

Julia Version 1.5.3
Commit 788b2c77c1 (2020-11-09 13:37 UTC)
Platform Info:
  OS: Windows (x86_64-w64-mingw32)
  CPU: AMD Ryzen 5 2600X Six-Core Processor
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-9.0.1 (ORCJIT, znver1)
Environment:
  JULIA_EDITOR = "C:\Users\user\AppData\Local\atom\app-1.54.0\atom.exe"  -a
  JULIA_NUM_THREADS = 12

Pkg.status()

[c52e3926] Atom v0.12.30
  [6e4b80f9] BenchmarkTools v0.5.0
  [a076750e] CPLEX v0.7.6
  [336ed68f] CSV v0.8.2
  [5ae59095] Colors v0.12.6
  [a93c6f00] DataFrames v0.22.2
  [864edb3b] DataStructures v0.17.20
  [41bf760c] DiffEqSensitivity v6.35.0
  [0c46a032] DifferentialEquations v6.16.0
  [31c24e10] Distributions v0.23.8
  [bb8be931] EAGO v0.5.2
  [f6369f11] ForwardDiff v0.10.14
  [7073ff75] IJulia v1.23.1
  [d1acc4aa] IntervalArithmetic v0.17.6
  [b6b21f68] Ipopt v0.6.5
  [4076af6c] JuMP v0.21.4
  [e5e0dc1b] Juno v0.8.4
  [53c679d3] McCormick v0.10.3
  [1dea7af3] OrdinaryDiffEq v5.42.3
  [91a5bcdd] Plots v1.10.1
  [d330b81b] PyPlot v2.9.0
  [90137ffa] StaticArrays v0.12.5

Differentiable McCormick relaxation generates NaN

Differentiable McCormick relaxation (Diff) produces:
{2,Diff}(NaN, NaN, [NaN, NaN], [NaN, NaN], [NaN, NaN], true),
while Nonsmooth McCormick relaxation (NS) produces:
{2,NS}(-0.3612000000000003, -0.36120000000000035, [-0.361201, -0.3612], [-0.0, -0.0], [-0.0, -0.0], true)

McCormick.jl version: v0.10.1

MWE:

using McCormick

x = [1.2, 1.1]
p = [3.01, 1.01]

xI = [Interval(x[i]) for i=1:2]
pI = [Interval(p[i]) for i=1:2]

xMC = [MC{2, Diff}(xI[i]) for i=1:2]
pMC = [MC{2, Diff}(pI[i]) for i=1:2]

f(x,p) = p[1]*x[1]*(1.0 - x[2])

println(f(xMC,pMC))

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.