澳门新葡萄京官网注册 1

julia> ]pkg> stpkg> up PackageCompiler

1.1 关于Julia

Julia语言是高性能、动态编译的高级计算机语言。它具有极强的灵活性,适合于解决数值和科学计算问题,拥有与传统的静态型语言相媲美的执行速度。Julia语言的开发目的是创建一个功能强大、易用性好和高效的单一语言环境。

Julia语言创始人为若干精通科学计算的编程人员,其源代码以及各种平台的可执行文件及专业编译器Juno可在
http://julialang.org
网站下载。Julia语言可以通过基于网页的Jupyter (IJulia)
交互环境执行,方便在教学等情景下展示执行结果。

作为新的高性能、编译型、动态交互式的高级编程语言,Julia集中了许多计算机语言的优点。

它拥有类似于C语言一样的执行速度,拥有如同Ruby语言的动态性,又有Matlab般熟悉的数学记号和线性代数运算能力,兼具像Python般的通用性,又像R语言一样擅长于统计分析,并有Perl般处理字符串的能力和shell等胶水语言的特点,并易于学习

使用七种标准检查程序,Julia语言的运行速度接近于C及Fortran语言,但其编写数值计算程序的速度却快得多。一般情况下,Julia语言运行的数值计算程序时的速度也接近于C++,是R语言速度的100倍,Matlab语言的1000倍。

(文/Solidot)    

对于我来说,学习一门新的语言,我都会从它的特性开始入手,比如说特定的数据类型:

1.2 Julia 语言的下载与安装

Julia的官方网站是
http://julialang.org/

IJulia是整合IPython前端和Julia语言的交互式网页编程环境,允许用户通过Jupyter或IPython的强大图形界面使用Julia语言。用户可在一个文件中同时使用代码、格式化文本、数学公式和多媒体。IJulia文件也可加载NBInclude包单独运行。

Pkg.add("IJulia")

Pkg.build("IJulia")

可以使用两种方式启动IJulia:

using IJulia

notebook()

jupyter notebook

这笔捐钱将在两年内拨给Julia开发团队。该基金会的一个目标是创造出更高效更强大的科学计算工具去帮助数值驱动的研究。
 

写个根号都那么任性!

2. Julia语言基础

Julia语言中单行注释只需要一个”#”,多行注释只需要以”#=”开始“#=”结束。

摩尔基金会向 Julia
编程语言捐款60万美元,以资助开发团队加快进度开发出生产版本。Julia
是一个数值和科学计算的动态语言,结合Matlab和R的长处,易于编程,提供了类似C语言的性能。Julia
于2012年发布了第一个版本,最新稳定版本还是0.4。

此时就可以把 PackageCompiler
升级到最新版本,可以进行编译了,切记,在编译前重启
REPL
,否则加载到的依然是老版本的包。

1. Julia 语言简介

澳门新葡萄京官网注册,本地化编译,这是一个非常有用的特性,可以让执行效率变得更高,同时更容易分发软件。在
Julia
里做本地化编译目前还是有一些麻烦的,官方提供的编译工具并不那么好用,如下:

3. 学习资源

  1. 斯坦福大学的“应用矩阵方法(EE103: Introduction to Matrix
    Methods)”
  2. 麻省理工学院的“线性代数(18.06: Linear
    Algebra)”
  3. JuliaPro等资源下载
  4. 中文版官方文档
  5. Stats Learning By
    Examples
  6. Julia for Data
    Science
  7. The Julia
    Express

澳门新葡萄京官网注册 2

2.1 变量、矩阵及向量

二维数组以分号分隔维度。

matrix = [1 2; 3 4]

2×2 Array{Int64,2}:
 1  2
 3  4

X = [1 2
     3 4]
X'X # X矩阵转置后乘X

2×2 Array{Int64,2}:
 10  14
 14  20

数组存储一列值,index从1开始

a = Int64[]

0-element Array{Int64,1}

一维数组可以以逗号分隔值的方式声明

b = [4, 5, 6]

3-element Array{Int64,1}:
 4
 5
 6

输出包含3个Int64类型元素的数组: [4, 5, 6]

b[1]

4

end可以直接取到最后索引,可用作任何索引表达式

b[end]

6

使用push!append!往数组末尾添加元素

push!(a, 1)

1-element Array{Int64,1}:
 1

push!(a, 2)

2-element Array{Int64,1}:
 1
 2

用pop弹出末尾元素

pop!(b)

6

以叹号结尾的函数名表示它会改变参数的值

arr = [5, 4, 6]

3-element Array{Int64,1}:
 5
 4
 6

sort(arr)

3-element Array{Int64,1}:
 4
 5
 6

sort!(arr)

3-element Array{Int64,1}:
 4
 5
 6

arr现在变成了[4, 5, 6]

arr

3-element Array{Int64,1}:
 4
 5
 6

可以用range初始化数组

a = collect(1: 5)

5-element Array{Int64,1}:
 1
 2
 3
 4
 5

用length获得数组长度

length(a)

5

可以将tuples元素分别赋给变量

a, b, c = (1, 2, 3)

(1, 2, 3)

现在 $a=1, b=2, c=3$

字典用Dict生成

empty_dict = Dict()

Dict{Any,Any} with 0 entries

也可以用字符串创建字典

filled_dict = Dict("one"=>1, "two"=>2, "three"=>3)

Dict{String,Int64} with 3 entries:
  "two"   => 2
  "one"   => 1
  "three" => 3

使用get(dictionary, key, defalt_value)可以提供默认值来避免异常

get(filled_dict, "one", 4)

1

类似Matlab构造矩阵

ones(2,3)

2×3 Array{Float64,2}:
 1.0  1.0  1.0
 1.0  1.0  1.0

$2times 3$维的随机矩阵,保留两位有效数字

A = round(randn(2,3), 2)

2×3 Array{Float64,2}:
  0.28  1.0   -0.93
 -0.37  1.85   0.63

改变矩阵元素

A[1,2] = 1000

1000

M = Array(Float64, 2, 3) #未初始化的矩阵

2×3 Array{Float64,2}:
 2.30147e-314  0.0           2.30002e-314
 0.0           2.30138e-314  0.0

fill!(M, 3.0) #矩阵M填补元素

2×3 Array{Float64,2}:
 3.0  3.0  3.0
 3.0  3.0  3.0

I = eye(3) #单位针

3×3 Array{Float64,2}:
 1.0  0.0  0.0
 0.0  1.0  0.0
 0.0  0.0  1.0

M2 = vcat(M,I) #垂直合并矩阵

5×3 Array{Float64,2}:
 3.0  3.0  3.0
 3.0  3.0  3.0
 1.0  0.0  0.0
 0.0  1.0  0.0
 0.0  0.0  1.0

M2 = reshape(M2, 3, 5) #重新制定矩阵形状

3×5 Array{Float64,2}:
 3.0  0.0  3.0  0.0  0.0
 3.0  0.0  0.0  3.0  0.0
 1.0  3.0  1.0  3.0  1.0

M3 = copy(M2) #复制矩阵

3×5 Array{Float64,2}:
 3.0  0.0  3.0  0.0  0.0
 3.0  0.0  0.0  3.0  0.0
 1.0  3.0  1.0  3.0  1.0

M3[2:end,[1,3]] #子矩阵

2×2 Array{Float64,2}:
 3.0  0.0
 1.0  1.0

x = [1:3;]
s = [x[i]^2+1 for i=1:length(x)] #类似python构造矩阵

3-element Array{Int64,1}:
  2
  5
 10

a = [1, 2, 3]
a.*a #矩阵元素级操作

3-element Array{Int64,1}:
 1
 4
 9

m = [1, 2, 3]
println(repmat(m, 2, 3)) #水平方向重复矩阵构建新矩阵
println(repeat(m, inner=[2,3])) #垂直方向重复矩阵构建新矩阵

[1 1 1; 2 2 2; 3 3 3; 1 1 1; 2 2 2; 3 3 3]
[1 1 1; 1 1 1; 2 2 2; 2 2 2; 3 3 3; 3 3 3]

a = [10.0 1.0]
b = [0.1 0.2; 0.3 0.4]
broadcast(+,a,b) #矩阵广播操作

2×2 Array{Float64,2}:
 10.1  1.2
 10.3  1.4

spzeros(2,3) #稀疏矩阵

2×3 SparseMatrixCSC{Float64,Int64} with 0 stored entries

S = speye(2,3) #单位稀疏矩阵

2×3 SparseMatrixCSC{Float64,Int64} with 2 stored entries:
  [1, 1]  =  1.0
  [2, 2]  =  1.0

findnz(S) #稀疏矩阵的指数和元素

([1, 2], [1, 2], [1.0, 1.0])

D=full(S) #稀疏矩阵转变为满矩阵

2×3 Array{Float64,2}:
 1.0  0.0  0.0
 0.0  1.0  0.0

X = [1 2; 3 4]
kron(X,X) #矩阵的Kronecker乘法

4×4 Array{Int64,2}:
 1   2   2   4
 3   4   6   8
 3   6   4   8
 9  12  12  16

y = [3,10]
X'XX'y #解方程组

2-element Array{Float64,1}:
  4.0
 -0.5

rank(X) #矩阵的秩

2

println(trues(2,3)) #Bool型矩阵

Bool[true true true; true true true]

isposdef(X'X) #判断矩阵是否正定

true

eig(X'X) #广义矩阵特征值和广义特征向量

([0.133931, 29.8661], [-0.817416 0.576048; 0.576048 0.817416])

chol(X'X) #矩阵Cholesky分解

2×2 UpperTriangular{Float64,Array{Float64,2}}:
 3.16228  4.42719
  ⋅       0.632456

a = [1 4 5
     5 5 1
     2 2 4]
sortrows(a, by=x->(x[2],x[1]), rev=true) #依矩阵 第二列元素进行排序

3×3 Array{Int64,2}:
 5  5  1
 1  4  5
 2  2  4

a = [3, 7, 9]
find(x->x>4, a) #查找矩阵a中大于4的元素

2-element Array{Int64,1}:
 2
 3

虽然在这种情况下写代码的确是累了点,但是效果很好,能够很直观的看出来想要做的事情。

2.2 函数

用关键字functionend可创建一个新函数

function change1(y)
    y = y + [2, 2, 2]
    println(y)
end
function change2(y)
    y = y + [1, 2, 3]
    println(y)
end
function change3(y)
    y[1] = y[1]
    println(y)
end

change3 (generic function with 1 method)

d = [1, 2, 3]
change1(d)
change2(d)
change3(d)

[3, 4, 5]
[2, 4, 6]
[1, 2, 3]

可以定义接受可变长参数的函数

function varargs(args...)
    return args
    # 关键字 return 可在函数内部任何地方返回
end

varargs (generic function with 1 method)

varargs(1,2,3)

(1, 2, 3)

定义可选参数的函数

function defaults(a, b, x=5, y=6)
    return "$a $b and $x $y"
end

defaults (generic function with 3 methods)

defaults('h', 'g')

"h g and 5 6"

安装后只需要配置 Julia 的可执行程序路径即可,比如说在 Mac 下是
/Applications/Julia-x.y.app/Contents/Resources/julia/bin/julia。于是环境就搭好了,可以愉快的玩耍了。

2.4 类型

用户可以用typeof函数来获得值的类型

typeof(5)

Int64

用户还可以自定义类型,用typeend关键字定义新的类型

type Tiger
    taillength::Float64
    coatcolor #不带类型标注相当于Any类型
end

tigger = Tiger(3.6, "orange")

Tiger(3.6, "orange")

抽象类型不能被实例化,但是可以有子类型

type Lion <: Tiger # Lion是Cat的子类型
    mane_color
    roar::String
end

Julia语言全面支持面向对象编程的基本特征,如继承性,多态性等。

julia> x = 1 / Inf0.0julia> y = 0 * InfNaN

2.3 控制流

if语句,用来判定所给定的条件是否满足,根据判定的结果(真或假)决定执行

var = 5
if var > 10
    println("var is totally bigger than 10.")
elseif var < 10
    println("var is smaller than 10.")
else
    println("var is indeed 10.")
end

var is smaller than 10.

for循环, Iterable类型包括Range,Array,Set,Dictionary,以及String

for animal = ["dog", "cat", "mouse"]
    println("$animal is a mammal.")
end

dog is a mammal.
cat is a mammal.
mouse is a mammal.

x = 0
while x < 4
    println(x)
    x += 1
end

0
1
2
3

查了一下 github 的提交记录,发现最新的 PackageCompiler 0.6.0
已经可以适配 Julia 1.1 了,然而我们通过 Pkg 安装来的 PackageCompiler
却是 0.5.1 的,必须先进行升级:

julia> using PackageCompilerjulia> build_executable("sample.jl")

当用上 Julia 之后,就可以直接扔掉 MPS 了,你可以用很简单的方式,在 Julia
里编写数学公式:

对于 Julia 来说,要编译一个本地化应用,需要一个与 C 一致的 main
函数,作为程序的执行入口,所以我们可以把代码修改成这样:

julia> x = 3julia> y = 2x^2 + 3x - 1julia> printlnjulia> z = √2julia> println

既然要拿它来进行开发了,那自然逃不了搭建开发环境等事。好在 Julia
提供了非常简单搭建手册,直接照做就行了。

julia> using Pkgjulia> Pkg.add("PackageCompiler")julia> using PackageCompilerjulia> build_executable("sample.jl")

或许你根本没听说过还有这么一门语言,我也是最近才接触到它,瞬间就被它的高效简洁所吸引,这里所指的高效,同时包含了编码与执行两层含义。我曾经非常想在
Java 或 Kotlin 内直接书写数学公式,因此也学习了 MPS
等奇怪的东西,比如说这样的(图片来源为 JetBrains MPS Intro):

然后在 Julia 命令行下进行编译就可以了:

Julia
已拥有很多第三方库,可以直接在包管理工具内进行安装,默认是不安装的。在安装的过程中,也有可能会出现问题,多是因为国内网络的问题,导致一些包无自法下载,请自行寻找解决方案。在网络完备的前提下,使用以下命令可以完成对网络请求库,以及
JSON 解析库的安装:

ERROR: Unexpected format of "Base.julia_cmd()", you may be using an incompatible version of Julia
using HTTPusing JSONhttpRequest = ( ret = HTTP.request("GET", url); cb(ret.status, String))httpRequest("http://httpbin.org/ip", (code, body) -> ( println; println; json = JSON.parse; ip = json["origin"]; println

是不是发现新大陆了?在其他的编程语言里,对 -1 开根号必然是报错的,然而在
Julia 里,居然支持虚数单位,这个特性已经可以决定 Julia
必然在科学计算领域里能大有作为。同样的,还有一些常规语言不具备的概念性的东西:

经过漫长的等待,就可以看到原本可执行程序已生成。就目前来看,编译效率实在是非常低,并且在编译结果中还带有一大堆的依赖库,对发布程序造成一些不便。

这两句代码在一开始绝对会让你体会到什么叫生不如死,因为编译时会报错:

julia> using Pkgjulia> Pkg.addjulia> Pkg.addjulia> Pkg.build("MbedTLS")

搭过一遍后,我发现我这种 Idea 党完全用不惯 Atom,还是更加倾向于在 Idea
里直接搭建。不得不说,JetBrains 全家桶真的是万能的,直接就找到了 Julia
的插件:

下面也要尝试一下,Julia 对于常规编程的支持是否友好,我选择的是网络请求和
JSON 解析的能力。

不过不论如何,我们已经成功上手了
Julia,可以使用它来做一些开发了,比较看重它的跨平台特性以及对科学计算的能力,同样的,极其方便的代码编写方式,良好的语言胶水特性,也是非常到位的继续使用的理由。

可以很明确的看到,Julia 和 Kotlin 一样,都把函数视为一等公民,并且 Julia
更智能,并不需要传入函数的定义。在这一点是,是仁者见仁的,因为这样的特性存在,也强迫我们必须写较多的注释,否则后期自己的代码都无法维护了。

在这里的 Inf 就是无穷大,而 NaN 即是表示
并非是一个数字(Not a Number)。这些概念的引入,使得 Julia
更加适合被用在科学计算上。当然了,Julia
所包含的并不仅仅有这些概念而已,通过查阅手册,可以了解到更多的令人激动的特性。

julia> x = √Complex0.0 + 1.0im

澳门新葡萄京官网注册 3

然后只需要一点点代码,就能完成一个简易的请求了:

module GetIPimport HTTPimport JSONhttpRequest = ( ret = HTTP.request("GET", url); cb(ret.status, String))Base.@ccallable function julia_main(ARGS::Vector{String})::Cint httpRequest("http://httpbin.org/ip", (code, body) -> ( json = JSON.parse; ip = json["origin"]; println return 0endend