1. 文件读写
语法和python很像,读文件使用open-readlines-close,写文件使用open-println(file,data)-close
使用DelimitedFiles包中的readlm()读取csv文件。
读文件:
readline读取一行;readlines读取所有行为一个数组;eachline读取为一个迭代器:
写文件:
2. 与python/c/Fortran交互
通过PyCall包,Julia可以直接调用Python包。例如:
using PyCall
np= pyimport("numpy")
x = np.linspace(1, 10, 10)
数值、布尔、字符串、IO stream、函数、元组、数组或列表、以及包含这些类型的字典等,它们都会自动进行类型的转换(Python函数会被转换或传递为Julia的函数,反之亦然)。其它类型则是通过通用的PyObject提供的。
下面是调用c函数的例子。
ccall((:clock, "libc"), Int32, ()) # 调用C的clock函数
3. 绘图
3.1 pyplot
既然都装了python了,就用pyplot绘图吧。
using PyPlot
x=1:10
xlabel("x")
y=ones(10)
for i=1:10
y[i]=-i*i*i
end
ylabel("y")
title("XKCD plot")
plot(x,y)
另一种方式:
第三种方式:
3.2 使用Images
using Images
url = "..."
download(url,"test.jpg")
load("test.jpg")
下载图片,并绘制原图
3.3 skimage
pyplot()
@pyimport skimage.io as io
io.imshow("test.jpg") # 也可以直接放链接
3.4 Plots
using Plots
import FileIO
pyplot()
plot(FileIO.load("test.jpg"))
4. 数学工具
最小二乘拟合:LsqFit包,实现了LM算法
数值微分:Calculus包
数值积分:QuadGK包
自动微分:FowardDiff包
图论:LightGraphs包
OR接口:JuMP包。
下面是个例子,注意下标从1开始,使用Int和Bin表示整数和0-1变量
using JuMP,GLPK
m = Model(GLPK.Optimizer)
@variable(m,0<=x<=2)
@variable(m,0<=y<=2)
@objective(m,Max,5x+3y)
@constraint(m,1x+5y<=3.0)
JuMP.optimize!(m)
println(JuMP.value(x),",",JuMP.value(y),",",JuMP.objective_value(m))
julia中的slice是copy操作,引用操作需要使用view。注意shape也是view操作。
z = view(v,3:5)
# or use macro
z = @views v[3:5]
5. 基准测试
使用@timeit、@time 来做基本的测试
使用
m = randn(1<<16, 8)
function test_swaprow(m::VecOrMat)
N = size(m, 1)
for i = 1:N-1
swaprows!(m, i, i+1)
end
m
end
using BenchmarkTools
@benchmark test_swaprow($m)
返回
BenchmarkTools.Trial:
memory estimate: 25.97 MiB
allocs estimate: 653308
--------------
minimum time: 12.866 ms (7.65% GC)
median time: 17.959 ms (8.86% GC)
mean time: 18.326 ms (10.94% GC)
maximum time: 27.736 ms (12.75% GC)
--------------
samples: 273
evals/sample: 1
function swaprows!(v::VecOrMat{T}, i::Int, j::Int) where T
for c = 1:size(v, 2)
temp = v[i, c]
v[i, c] = v[j, c]
v[j, c] = temp
end
v
end
@benchmark test_swaprow($m)
BenchmarkTools.Trial:
memory estimate: 0 bytes
allocs estimate: 0
--------------
minimum time: 1.459 ms (0.00% GC)
median time: 1.524 ms (0.00% GC)
mean time: 1.582 ms (0.00% GC)
maximum time: 2.926 ms (0.00% GC)
--------------
samples: 3147
evals/sample: 1
6. 模块
模块是一些互相隔离的工作空间,用法上类似于Python中的库。模块中的export是将这函数导出来,这样就可以直接使用。如下:
module mytest
export myAdd
myAdd(x,y)=x+y
end
调用时,先include,然后就可以直接使用了
7. 宏
使用macro定义宏,然后使用@引用宏。总体来说非常像function
8 并行计算
8.1 协程/任务
协程也称为任务,如果一个计算以任务的方式执行,那它就很可能会被其他任务中断,原先的任务在恢复后,会从被中断的地方继续工作,这种过程看似很像函数调用,但有两点不同:1)任务切换不需要任何空间,因此可以完成任意数量任务的切换,而且无需考虑堆栈问题。2)任务切换可以按照任何顺序来进行。
任务比较适合生产者-消费者模式,一个过程用来生产值,另一个用来消费值。消费者不能简单的调用生产者来得到值,因为两者的执行时间不一定协同,但是在任务中,两者则可以正常运行。
Julia中提供了Channel来解决生产者消费者的协同问题,其实Channel就是一个FIFO(first-in first-out)队列。使用put!和take!(或是fetch,不删除)函数来具体实现。任务的一个特性就是随着任务的结束,channel对象会自动关闭,无需人为干预。
如果一个 Channel 是空的,读取的 task(即执行 take! 的task)会被阻塞直到有新的数据准备好了;如果一个 Channel 是满的,那么写入的 task(即执行 put! 的 task)则会被阻塞,直到 Channel 有空余。在控制台里面表现为堵塞住,无法继续执行命令
isready 可以用来检查一个 channel 中是否有已经准备好的元素,而等待一个元素准备好 则用 wait。
Channel也可以接收一个函数,介绍及示例如下:
接下来看下任务的调度。用@task定义,然后用schedule进行调度。
8.2 线程
使用Threads.nthreads()查看当前的线程数,默认是启动一个线程。
使用export JULIA_NUM_THREADS=4(Linux OSX)或set JULIA_NUM_THREADS=4(Windows)来设置启动4个线程。当我们要在Jupyter中使用多个线程时,可以在Julia的运行目录中下打开命令行,先设置线程数,再启动Julia。
其中Ref和[]分别是取地址和引用。
8.3 进程
多进程也叫多核心或者分布式处理,就是用一个CPU的多个核心或者多个CPU进行编程。使用julia -p n启动多进程,也可以进入后添加。
Julia 中的分布式编程基于两个基本概念:远程引用(remote references)和远程调用(remote calls)。远程引用是一个对象,任意一个进程可以通过它访问存储在某个特定进程上的对象。远程调用指是某个进程发起的执行函数的请求,该函数会在另一个(也可能是同一个)进程中执行。
远程引用有两种类型:Future 和 RemoteChannel。
一次远程调用会返回一个 Future 作为结果。
远程调用会立即返回;也就是说,执行远程调用的进程接下来会继续执行下一个操作,而远程调用则会在另外的进程中进行。你可以通过对返回的 Future 执行 wait 操作来等待远程调用结束,然后用 fetch 获取结果。
对于 RemoteChannel 而言,它可以被反复写入。
例如,多个进程可以通过引用同一个远程 Channel 来协调相互之间的操作。
每个进程都有一个对应的 id,提供 Julia 交互环境的进程的 id 永远是1。我们把用来执行并行任务的进程称为 “worker”,假如总共只有一个进程,那么进程1就被认为是 worker,否则,除了进程1以外的进程都称作 worker。
9. 概率相关
9.1 基本用法
9.2 综合例子
rand:uniform分布
StatsBase.countmap:统计列表中每个元素的个数,生成一个字典
bar可以直接绘制字典
下面是个综合例子: