Tag Archives: dữ liệu

Julia qua các ví dụ

Một tập hợp các ví dụ không “chính thống” về lập trình Julia – một ngôn ngữ lập trình động, bậc cao, hiệu năng cao dành cho tính toán kĩ thuật.

Dưới đây là một loạt các ví dụ về những phép tính thông dụng trong Julia. Coi như là bạn đã cài đặt Julia vào máy và khởi động rồi (các ví dụ này đã được kiểm tra với Julia v1.0.5).

https://juliabyexample.helpmanual.io

Hello World

Mã lệnh đơn giản nhất có thể.

println("hello world")
#> hello world

Với Julia đã được cài đặt và thêm vào đường dẫn trong máy tính của bạn, mã lệnh này có thể được chạy bằng cách gõ julia hello_world.jl. Cũng có thể chạy nó từ dấu nhắc lệnh trong Julia bằng cách gõ include("hello_world.jl"), bằng cách thứ hai này sẽ tính toán tất cả những biểu thức hợp lệ có trong file chương trình và trả lại kết quả của biểu thức cuối cùng.

Các hàm đơn giản

Ví dụ trên cho thấy hai hàm đơn giản, cách gọi chúng và in kết quả. Những ví dụ kĩ hơn về định dạng số sẽ được trình bày sau đây.

# hàm để tính thể tích một khối cầu 
function sphere_vol(r)
    # julia cho phép đặt tên theo font Unicode (UTF-8). Xem thêm: https://docs.julialang.org/en/v1/manual/unicode-input/#Unicode-Input-1
    # (bạn có thể viết các tên hàm, tên biến bằng chữ tiếng Việt có dấu 
    # Vì dùng font Unicode, bạn có thể viết "pi" hoặc kí hiệu π 
    return 4/3*pi*r^3
end

# hàm có thể được định nghĩa gọn hơn, ví dụ như hàm tính nghiệm PT bậc 2 dưới đây
quadratic(a, sqr_term, b) = (-b + sqr_term) / 2a

# giải PT bậc 2: 0 = a*x^2+b*x+c để tìm x, các kiểu đối số có thể được định nghĩa từ đầu 
# (xem thêm về kiểu đối số: https://docs.julialang.org/en/v1/manual/functions/#Further-Reading-1)
function quadratic2(a::Float64, b::Float64, c::Float64)
    # khác với những ngôn ngữ khác, 2a ở đây tương đương với 2*a
    # a^2 được dùng thay cho a**2 hoặc pow(a,2)
    sqr_term = sqrt(b^2-4a*c)
    r1 = quadratic(a, sqr_term, b)
    r2 = quadratic(a, -sqr_term, b)
    # một hàm có thể trả lại nhiều giá trị bằng các cặp (tuple)
    # nếu bỏ qua từ khoá return, thì biểu thức cuối cùng sẽ được trả lại
    r1, r2
end

vol = sphere_vol(3)
# @printf cho phép định dạng số nhưng không tự động chèn thêm dấu xuống dòng \n vào câu lệnh, xem dưới đây
using Printf
@printf "volume = %0.3f\n" vol 
#> volume = 113.097

quad1, quad2 = quadratic2(2.0, -2.0, -12.0)
println("nghiệm 1: ", quad1)
#> result 1: 3.0
println("nghiệm 2: ", quad2)
#> result 2: -2.0

Cơ bản về chuỗi

Tập hợp các ví dụ khác nhau về chuỗi (đánh chỉ số chuỗi cũng giống như đánh chỉ số mảng: xem bên dưới).

# các chuỗi được xác định bằng cặp dấu nháy kép
# cũng như các biến, chuỗi có thể chứa bất kì kí tự Unicode nào
s1 = "The quick brown fox jumps over the lazy dog α,β,γ"
println(s1)
#> The quick brown fox jumps over the lazy dog α,β,γ

# println sẽ xuống dòng sau khi in xong 
# print cũng có thể dùng nếu bạn không muốn xuống dòng
print("this")
#> this
print(" and")
#> and
print(" that.\n")
#> that.

# các kí tự được định nghĩa bằng cặp nháy đơn 
c1 = 'a'
println(c1)
#> a
# giá trị ascii của một kí tự có thể nhận được bằng hàm Int():
println(c1, " ascii value = ", Int(c1))
#> a ascii value = 97
println("Int('α') == ", Int('α'))
#> Int('α') == 945

# do vậy bạn phải thấy được
println(Int('1') == 1)
#> false

# các chuỗi có thể được chuyển đổi về dạng viết chữ in hoặc chữ thường:
s1_caps = uppercase(s1)
s1_lower = lowercase(s1)
println(s1_caps, "\n", s1_lower)
#> THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG Α,Β,Γ
#> the quick brown fox jumps over the lazy dog α,β,γ

# các chuỗi con có thể được đánh chỉ số như các mảng:
# (còn show sẽ in ra giá trị thô)
show(s1[11]); println()
#> 'b'

# hoặc có thể tạo được các chuỗi con:
show(s1[1:10]); println()
#> "The quick "

# end được dùng để chỉ vị trí cuối mảng hoặc chuỗi
show(s1[end-10:end]); println()
#> "dog α,β,γ"

# julia cho phép nội suy chuỗi (string interpolation):
a = "chào mừng"
b = "julia"
println("$a đến $b.")
#> chào mừng đến julia.

# cách này có thể dùng để tính các biểu thức:
println("1 + 2 = $(1 + 2)")
#> 1 + 2 = 3

# chuỗi cũng có thể được kết nối bằng toán tử *
# dùng * chứ không phải + có thể khiến bạn hơi bỡ ngỡ khi bắt đầu dùng Julia,
# nhưng người ta vẫn cho rằng dấu * là hợp lý hơn
s2 = "this" * " and" * " that"
println(s2)
#> this and that

# cũng như là dùng hàm string
s3 = string("this", " and", " that")
println(s3)
#> this and that

Chuỗi: Chuyển đổi và định dạng

# Các chuỗi có thể được chuyển đổi bằng floatint:
e_str1 = "2.718"
e = parse(Float64, e_str1)
println(5e)
#> 13.59
num_15 = parse(Int, "15")
println(3num_15)
#> 45

# Các số có thể được chuyển thành chuỗi và định dạng bằng printf
using Printf
@printf "e = %0.2f\n" e
#> e = 2.72
# hoặc để tạo chuỗi mới bằng sprintf
e_str2 = @sprintf("%0.3f", e)

# Để cho thấy rằng 2 chuỗi giống hệt nhau không 
println("e_str1 == e_str2: $(e_str1 == e_str2)")
#> e_str1 == e_str2: true

# Các kí tự để định dạng số gồm có f, e, a, g, c, s, p, d:
# (pi là một hằng số định nghĩa trước; tuy nhiên vì dạng của nó là
# "MathConst", nó cần được chuyển đổi thành dạng dấu phẩy động trước khi định dạng)
@printf "cố định phần thập phân: %0.3f\n" float(pi)
#> cố định phần thập phân: 3.142
@printf "dạng khoa học: %0.6e\n" 1000pi
#> dạng khoa học: 3.141593e+03
@printf "dấu phẩy động định dạng hex (16): %a\n" 0xff
#> dấu phẩy động định dạng hex (16): 0xf.fp+4
@printf "cố định phần thập phân: %g\n" pi*1e8
#> cố định phần thập phân: 3.14159e+08
@printf "một kí tự: %c\n" 'α'
#> một kí tự: α
@printf "một chuỗi: %s\n" "look I'm a string!"
#> một chuỗi: look I'm a string!
@printf "căn lề phải chuỗi sau trong khoảng 50 kí tự: %50s\n" "width 50, text right justified!"
#> căn lề phải chuỗi sau trong khoảng 50 kí tự:                    width 50, text right justified!
@printf "một con trỏ: %p\n" 100000000
#> một con trỏ: 0x0000000005f5e100
@printf "in ra một số nguyên: %d\n" 1e10
#> in ra một số nguyên: 10000000000

Thao tác với chuỗi

s1 = "The quick brown fox jumps over the lazy dog α,β,γ"

# search trả lại chỉ số đầu tiên của một kí tự
i = findfirst(isequal('b'), s1)
println(i)
#> 11
# tham số thứ hai tương đương với tham số thứ hai trong hàm split, xem dưới đây 

# hoặc một khoảng nếu ta gọi nó với một chuỗi khác
r = findfirst("brown", s1)
println(r)
#> 11:15


# cách thay thế chuỗi được làm như sau:
r = replace(s1, "brown" => "red")
show(r); println()
#> "The quick red fox jumps over the lazy dog α,β,γ"

# tìm kiếm và thay thễ cũng có thể nhận các biểu thức thường quy (regular expressions) bằng cách viết 'r' phía trước chuỗi:
r = findfirst(r"b[\w]*n", s1)
println(r)
#> 11:15

# một lần nữa với biểu thức thường quy
r = replace(s1, r"b[\w]*n" => "red")
show(r); println()
#> "The quick red fox jumps over the lazy dog α,β,γ"

# cũng có những hàm cho các biểu thức thường quy để trả lại những kiểu RegexMatch
# match sẽ rà soát từ trái qua phải để tìm vị trí khớp đầu tiên (hoặc ta có thể cho một chỉ số bắt đầu)
r = match(r"b[\w]*n", s1)
println(r)
#> RegexMatch("brown")

# Các kiểu RegexMatch có một thuộc tính match; thuộc tính này sẽ lưu giữ chuỗi được khớp 
show(r.match); println()
#> "brown"

# eachmatch trả lại một bộ lặp gồm tất cả những chuỗi khớp 
r = eachmatch(r"[\w]{4,}", s1)
for i in r print("\"$(i.match)\" ") end
#> "quick" "brown" "jumps" "over" "lazy"
println()


r = collect(m.match for m = eachmatch(r"[\w]{4,}", s1))
println(r)
#> SubString{String}["quick", "brown", "jumps", "over", "lazy"]

# một chuỗi có thể được lặp lại bằng hàm repeat, 
# hoặc viết gọn hơn bằng cú pháp ^:
r = "hello "^3
show(r); println() #> "hello hello hello "

# hàm strip có tác dụng giống như trong Python:
# ví dụ với một tham số, nó sẽ gọt bớt các dấu trống ở hai phía đầu chuỗi 
r = strip("hello ")
show(r); println() #> "hello"
# hoặc với một tham số thứ hai là một mảng các kí tự, hàm này sẽ gọt bất kì kí tự nào có tên trong bảng này
r = strip("hello ", ['h', ' '])
show(r); println() #> "ello"
# (chú ý: mảng chứa các kí tự chứ không phải các chuỗi)

# tương tự, split cũng có tác dụng cơ bản như trong Python:
r = split("hello, there,bob", ',')
show(r); println() #> SubString{String}["hello", " there", "bob"]
r = split("hello, there,bob", ", ")
show(r); println() #> SubString{String}["hello", "there,bob"]
r = split("hello, there,bob", [',', ' '], limit=0, keepempty=false)
show(r); println() #> SubString{String}["hello", "there", "bob"]
# (hai tham số cuối tương đương với limit và include_empty trong Python, xem các tài liệu)

# ngược lại với split, join, đơn giản như sau:
r = join(collect(1:10), ", ")
println(r) #> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10

Mảng

function printsum(a)
    # summary dùng để tạo ra thông tin tóm tắt về một đối tượng
    println(summary(a), ": ", repr(a))
end

# mảng có thể được khởi tạo trực tiếp:
a1 = [1,2,3]
printsum(a1)
#> 3-element Array{Int64,1}: [1, 2, 3]

# hoặc khởi tạo là mảng trống:
a2 = []
printsum(a2)
#> 0-element Array{Any,1}: Any[]

# vì mảng này không có kiểu, nên những hàm như push! (xem bên dưới) không dùng được
# thay vào đó, các mảng có thể được khởi tạo với một kiểu nhất định:
a3 = Int64[]
printsum(a3)
#> 0-element Array{Int64,1}: Int64[]

# các khoảng thì khác với mảng:
a4 = 1:20
printsum(a4)
#> 20-element UnitRange{Int64}: 1:20

# tuy nhiên, chúng có thể được dùng để tạo ra mảng, như sau:
a4 = collect(1:20)
printsum(a4)
#> 20-element Array{Int64,1}: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 
#>  15, 16, 17, 18, 19, 20]

# các mảng cũng có thể được tạo ra bằng cách liệt kê đầy đủ (comprehension):
a5 = [2^i for i = 1:10]
printsum(a5)
#> 10-element Array{Int64,1}: [2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]

# mảng cũng có thể chứa kiểu bất kì, nên ta có thể tạo ra mảng chứa các mảng:
a6 = (Array{Int64, 1})[]
printsum(a6)
#> 0-element Array{Array{Int64,1},1}: Array{Int64,1}[]
# (lưu ý: đây là một "mảng lồng ghép" (theo nghĩa một mảng chứa các mảng),
# chứ không phải mảng đa chiều - loại này không được đề cập ở đây).

# Julia cung cấp một số hàm cho hàng đợi hai đầu ("Dequeue"), 
# hàm thông dụng nhất để bổ sung vào cuối của mảng là push!
# dấu ! ở cuối tên hàm ngụ ý rằng tham số thứ nhất được cập nhật.

push!(a1, 4)
printsum(a1)
#> 4-element Array{Int64,1}: [1, 2, 3, 4]

# push!(a2, 1) sẽ gây lỗi:

push!(a3, 1)
printsum(a3) #> 1-element Array{Int64,1}: [1]
#> 1-element Array{Int64,1}: [1]

push!(a6, [1,2,3])
printsum(a6)
#> 1-element Array{Array{Int64,1},1}: Array{Int64,1}[[1, 2, 3]]

# sử dụng repeat() để tạo mảng
# bạn phải dùng các từ khoá "inner" và "outer"
# tất cả đối số phải là mảng (chứ không phải khoảng)
a7 = repeat(a1,inner=[2],outer=[1])
printsum(a7)
#> 8-element Array{Int64,1}: [1, 1, 2, 2, 3, 3, 4, 4]
a8 = repeat(collect(4:-1:1),inner=[1],outer=[2])
printsum(a8)
#> 8-element Array{Int64,1}: [4, 3, 2, 1, 4, 3, 2, 1]

Xử lý lỗi

# try, catch có thể được dùng để xử lý những lỗi, giống như các ngôn ngữ lập trình khác
try
    push!(a,1)
catch err
    showerror(stdout, err, backtrace());println()
end
#> UndefVarError: a not defined
#> Stacktrace:
#>  [1] top-level scope at C:\JuliaByExample\src\error_handling.jl:5
#>  [2] include at .\boot.jl:317 [inlined]
#>  [3] include_relative(::Module, ::String) at .\loading.jl:1038
#>  [4] include(::Module, ::String) at .\sysimg.jl:29
#>  [5] exec_options(::Base.JLOptions) at .\client.jl:229
#>  [6] _start() at .\client.jl:421
println("Continuing after error")
#> Continuing after error

Mảng đa chiều

Julia có khả năng làm việc với mảng đa chiều rất tốt. Hãy xem tài liệu hướng dẫn.

# repeat có thể giúp ích cho việc mở rộng một lưới số liệu
# cũng như hàm expand.grid() của ngôn ngữ lập trình R:

m1 = hcat(repeat([1,2],inner=[1],outer=[3*2]),
          repeat([1,2,3],inner=[2],outer=[2]),
          repeat([1,2,3,4],inner=[3],outer=[1]))
printsum(m1)
#> 12×3 Array{Int64,2}: [1 1 1; 2 1 1; 1 2 1; 2 2 2; 1 3 2; 2 3 2; 1 1 3; 2 1 3;
#>   1 2 3; 2 2 4; 1 3 4; 2 3 4]

# để lặp lại các mảng một cách đơn giản,
# hãy dùng repeat
m2 = repeat(m1,1,2)     # lặp a9 một lần theo chiều dim1 và hai lần theo chiều dim2
println("size: ", size(m2))
#> size: (12, 6)

m3 = repeat(m1,2,1)     # lặp a9 hai lần theo chiều dim1 và một lần theo chiều dim2
println("size: ", size(m3))
#> size: (24, 3)

# Phép liệt kê đầy đủ (comprehension) cũng là một cách khác để ta dễ dàng 
# tạo được những mảng đa chiều 

m4 = [i+j+k for i=1:2, j=1:3, k=1:2] # tạo nên một mảng 2x3x2 các phần tử kiểu Int64
m5 = ["Hi Im # $(i+2*(j-1 + 3*(k-1)))" for i=1:2, j=1:3, k=1:2]
# các biểu thức rất linh hoạt 
# bạn có thể chỉ định kiểu của mảng 
# chỉ bằng việc ghi nó phía trước biểu thức 
# (chẳng hạn, dưới đây chỉ định kiểu chuỗi `LegacyString.ASCIIString`
# cho các phần tử trong mảng).

import LegacyStrings
m5 = LegacyStrings.ASCIIString["Hi Im element # $(i+2*(j-1 + 3*(k-1)))" for i=1:2, j=1:3, k=1:2]
printsum(m5)
#> 2×3×2 Array{LegacyStrings.ASCIIString,3}: LegacyStrings.ASCIIString[
#>   "Hi Im element # 1" "Hi Im element # 3" "Hi Im element # 5";
#>   "Hi Im element # 2" "Hi Im element # 4" "Hi Im element # 6"]
#>
#> LegacyStrings.ASCIIString["Hi Im element # 7" "Hi Im element # 9"
#>   "Hi Im element # 11"; "Hi Im element # 8" "Hi Im element # 10" "Hi Im element # 12"]

# Thống kê trong mảng (array reduction)
# nhiều hàm trong Julia có một phương thức mảng 
# áp dụng được cho từng chiều riêng của một mảng:

sum(m4, dims=3)        # lấy tổng dọc theo chiều thứ ba
sum(m4, dims=(1,3))  # tổng dọc theo các chiều thứ nhất và thứ ba

maximum(m4, dims=2)    # tìm phần tử lớn nhất dọc theo chiều thứ 2
findmax(m4, dims=3)    # tìm phần tử lớn nhất cùng với chỉ số của nó dọc theo chiều thứ 3
                    # (hàm findmax chỉ có ở những phiên bản Julia gần đây)

# Quảng bá 
# khi bạn kết hợp các mảng có kích thước khác nhau trong cùng một phép toán 
# thì Julia sẽ cố gắng "trải ra" hoặc "quảng bá" mảng nhỏ hơn sao cho 
# hai mảng trở nên cùng kích thước. Toán tử quảng bá có một dấu chấm đứng trước:

m4 .+ 3       # cộng 3 vào tất cả phần tử
m4 .+ [1,2]      # cộng vec tơ [1,2] vào tất cả phần tử dọc theo chiều thứ nhất 

# lát cắt và khung ngắm 
m4 = m4[:,:,1] # giữ cố định chiều thứ 3 
m4[:,2,:]  # đó là một mảng 2x1x2, thật khó hình dung

# loại bỏ những chiều nào vốn chỉ có kích cỡ bằng 1:
dropdims(m4[:,2,:], dims=2) # thế này hay hơn

# gán những giá trị mới vào một khung ngắm nhất định
m4[:,:,1] = rand(1:6,2,3)
printsum(m4)
#> 2×3 Array{Int64,2}: [3 5 3; 1 3 5]

# (để xem thêm các ví dụ về try - catch, hãy trở lại Mục Xử lý lỗi bên trên)
try
    # lệnh kế tiếp sẽ gây lỗi; lẽ ra bạn phải gán kiểu dữ liệu đúng
    m4[:,:,1] = rand(2,3)
catch err
    println(err)
end
#> InexactError(:Int64, Int64, 0.7603891754678744)

try
    # lệnh kế tiếp sẽ gây lỗi; lẽ ra bạn phải gán hình dạng đúng 
    m4[:,:,1] = rand(1:6,3,2)
catch err
    println(err)
end
#> DimensionMismatch("tried to assign 3×2 array to 2×3×1 destination")

Từ điển

Julia sử dụng Dicts như các tập hợp có liên kết tương ứng. Cách dùng rất giống như ngôn ngữ Python, chỉ trừ cách viết định nghĩa => khá kì quặc.

# từ điển có thể được khởi tạo một cách trực tiếp:
a1 = Dict(1=>"one", 2=>"two")
printsum(a1) 
#> Dict{Int64,String} with 2 entries: Dict(2=>"two",1=>"one")

# và sau đó được bổ sung:
a1[3]="three"
printsum(a1) 
#> Dict{Int64,String} with 3 entries: Dict(2=>"two",3=>"three",1=>"one")
# (note dicts cannot be assumed to keep their original order)

# từ điển cũng có thể được tạo nên với kiểu dữ liệu được nêu rõ
a2 = Dict{Int64, AbstractString}()
a2[0]="zero"
printsum(a2)
#> Dict{Int64,AbstractString} with 1 entry: Dict{Int64,AbstractString}(0=>"zero")

# từ điển, cũng như các mảng, có thể được khởi tạo từ bản kê đầy đủ (comprehension)
using Printf
a3 = Dict([i => @sprintf("%d", i) for i = 1:10])
printsum(a3)
#> Dict{Int64,String} with 10 entries: Dict(7=>"7",4=>"4",9=>"9",10=>"10",
#>  2=>"2",3=>"3",5=>"5",8=>"8",6=>"6",1=>"1")

# như ta mong đợi, Julia có tất cả các hàm trợ giúp thong thường 
# đối với từ điển, chẳng hạn haskey
println(haskey(a1,1)) #> true

# vốn tương đương với 
println(1 in keys(a1)) #> true
# trong đó keys tạo ra một bộ lặp cho các khóa trong từ điển

# cũng giống như keys, values sẽ lấy bộ lặp cho các giá trị của từ điển:
printsum(values(a1)) 
#> Base.ValueIterator for a Dict{Int64,String} with 3 entries: ["two", "three", "one"]

# sử dụng collect để thu được một mảng
printsum(collect(values(a1)))
#> 3-element Array{String,1}: ["two", "three", "one"]

Vòng lặp và ánh xạ

Các vòng lặp for có thể được định nghĩa bằng nhiều cách.

for i in 1:5
    print(i, ", ")
end
#> 1, 2, 3, 4, 5,
# Trong các lời định nghĩa vòng lặp thì "in" tương đương với "=" 
# (tức là, lệnh trên sẽ tương đương với lệnh dưới)
for i = 1:5
    print(i, ", ")
end
println() #> 1, 2, 3, 4, 5,

# các mảng cũng có thể được lặp một cách trực tiếp:
a1 = [1,2,3,4]
for i in a1
    print(i, ", ")
end
println() #> 1, 2, 3, 4,

# continuebreak là các từ khoá hoạt động tương tự như lập trình Python:
a2 = collect(1:20)
for i in a2
    if i % 2 != 0
        continue
    end
    print(i, ", ")
    if i >= 8
        break
    end
end
println() #> 2, 4, 6, 8,

# Nếu mảng được xử lý trong quá trình tính toán, thì bạn cần phải dùng đến vòng lặp while.
# Hàm pop có tác dụng loại bỏ phần tử cuối trong một mảng 
while !isempty(a1)
    print(pop!(a1), ", ")
end
println() #> 4, 3, 2, 1,

d1 = Dict(1=>"one", 2=>"two", 3=>"three")
# Các từ điển (dict) có thể được lặp qua bằng hàm keys:
for k in sort(collect(keys(d1)))
    print(k, ": ", d1[k], ", ")
end
println() #> 1: one, 2: two, 3: three,

# Cũng như trong Python, ta có thể dùng enumerate để lấy được cả chỉ số và giá trị trong một vòng lặp:
a3 = ["one", "two", "three"]
for (i, v) in enumerate(a3)
    print(i, ": ", v, ", ")
end
println() #> 1: one, 2: two, 3: three,

# (lưu ý rằng enumerate sẽ bắt đầu từ 1 vì các mảng Julia được đánh chỉ số từ 1, không như Python)

# Hàm map (ánh xạ) có tác dụng như bạn hình dung: thực hiện một hàm cho trước đối với từng phần tử
# của một mảng hoặc một đối tượng lặp được, giống như phép liệt kê đầy đủ (comprehension)
a4 = map((x) -> x^2, [1, 2, 3, 7])
print(a4) 
println() #> [1, 4, 9, 49]

Tính toán theo điều kiện

Các câu lệnh if/else hoạt động giống như các ngôn ngữ lập trình khác – những phần tử boolean là true và false.

if true
    println("It's true!")
else
    println("It's false!")
end
#> It's true!

if false
   println("It's true!")
else
   println("It's false!")
end
#> It's false!

# Các số có thể được so sánh bằng các toán tử như <, >, ==, !=

1 == 1.
#> true

1 > 2
#> false

"foo" != "bar"
#> true

# và nhiều hàm trả lại các giá trị boolean

occursin("that", "this and that")
#> true

# Các câu lệnh logic phức tạp có thể thực hiện được nhờ `elseif`

function checktype(x)
   if x isa Int
      println("Look! An Int!")
   elseif x isa AbstractFloat
      println("Look! A Float!")
   elseif x isa Complex
      println("Số phức - complex!")
   else
      println("Tôi không biết đó là loại gì")
   end
end

checktype(2)
#> Look! An Int!

checktype(√2)
#> Look! A Float!

checktype(√Complex(-2))
#> Số phức - complex!

checktype("who am I?")
#> Tôi không biết đó là loại gì

# Với các phép toán logic đơn giản, ta có thể dùng toán tử "ba ngôi" (ternary operator) để cho gọn,
# toán tử này có dạng `mệnh_đề ? làm_nhánh_đúng : làm_nhánh_sai`

1 > 2 ? println("đúng rồi!") : println("sai rồi!")
#> sai rồi!

noisy_sqrt(x) = x ≥ 0 ? sqrt(x) : "Số âm mà!"
noisy_sqrt(4)
#> 2.0
noisy_sqrt(-4)
#> Số âm mà!

# "Định lượng đoản mạch" là một lựa chọn khác cho các câu lệnh điều kiện.
# Những toán tử `&&` nghĩa là AND (và), `||` nghĩa là OR (hoặc) chỉ định lượng 
# vế phải của câu lệnh nếu cần, tuỳ theo mệnh đề.
# Về mặt logic, nếu tôi muốn biết `42 == 0 AND x < y` đúng hay sai,
# thì bất kể `x` và `y` là gì đi nữa, chỉ cần vế trước là sai thì toàn bộ biểu thức là sai.
# This can be exploited to only evaluate a statement if something is true -
# the second statement doesn't even have to be boolean!

everything = 42
everything < 100 && println("đúng rồi!")
#> "that's true!"
everything == 0 && println("đúng rồi!")
#> false

√everything > 0 || println("sai rồi!")
#> true
√everything == everything || println("sai rồi!")
#> sai rồi!

Kiểu dữ liệu

Kiểu dữ liệu là yếu tố quan trọng khi bạn tạo cấu trúc dữ liệu trong Julia.

# Định nghĩa kiểu có lẽ gần sát với typedef trong C
# một kiểu dữ liệu đơn giản mà không có hàm tạo dựng (constructor) đặc biệt nào có thể viết như sau:
mutable struct Người
    tên::AbstractString
    nam_giới::Bool
    tuổi::Float64
    số_con::Int
end

p = Người("Julia", false, 4, 0)
printsum(p)
#> Người: Người("Julia", false, 4.0, 0)

nhóm = Người[]
push!(nhóm, Người("Steve", true, 42, 0))
push!(nhóm, Người("Jade", false, 17, 3))
printsum(nhóm)
#> 2-element Array{Người,1}: Người[Người("Steve", true, 42.0, 0), Người("Jade", false, 17.0, 3)]

# các kiểu cũng có thể chứa các mảng và từ điển 
# các hàm tạo dựng có thể được định nghĩa, để giúp ta dễ dàng tạo nên các đối tượng
mutable struct GiaĐình
    tên::AbstractString
    thành_viên::Array{AbstractString, 1}
    thêm::Bool
    # hàm tạo dựng nhận vào một tham biến và tạo nên giá trị mặc định còn lại 
    GiaĐình(tên::AbstractString) = new(tên, AbstractString[], false)
    # hàm tạo dựng nhận vào một tham biến và suy luận ra giá trị còn lại
    GiaĐình(tên::AbstractString, thành_viên) = new(tên, thành_viên, length(thành_viên) > 3)
end

gđ1 = GiaĐình("blogs")
println(gđ1)
#> GiaĐình("blogs", AbstractString[], false)
gđ2 = GiaĐình("jones", ["anna", "bob", "charlie", "dick"])
println(gđ2)
#> GiaĐình("jones", AbstractString["anna", "bob", "charlie", "dick"], true)

Đầu vào và đầu ra

Cú pháp cơ bản để đọc và ghi file trong Julia thì cũng tương tự như với Python.

File simple.dat dùng trong ví dụ này có thể được lấy về từ Github.

fname = "simple.dat"
# dùng từ khóa 'do' nghĩa là file được tự động đóng lại
# như cách dùng "with" trong Python.
# simple.dat là một file đơn giản chứa hai dòng chữ 
# và hai con số, như nội dung của file được ghi ra dưới đây:
open(fname,"r") do f
    for line in eachline(f)
        println(line)
    end
end
#> this is a simple file containing
#> text and numbers:
#> 43.3
#> 17

f = open(fname,"r")
show(readlines(f)); println()
#> ["this is a simple file containing", "text and numbers:", "43.3", "17"]
close(f)

f = open(fname,"r")
fstring = read(f, String)
close(f)
println(summary(fstring))
#> String
print(fstring)
#> this is a simple file containing
#> text and numbers:
#> 43.3
#> 17

outfile = "outfile.dat"
# Việc ghi ra file cũng đơn giản
f = open(outfile, "w")
# Cả print và println đều dùng được như thông thường nhưng thêm f là tham biến đầu tiên cho hàm
println(f, "some content")
print(f, "more content")
print(f, " more on the same line")
close(f)

# sau đó ta có thể kiểm tra nội dung file vừa được ghi ra 
# "do" ở trên đã tạo ra một hàm khuyết danh và truyền nó đến open
# ta có thể suy luận tương tự, từ đó truyền readall, qua đó gom gọn tất cả 
# open, read và close file vào cùng một dòng 
outfile_content = open(f->read(f, String), outfile, "r")
println(repr(outfile_content))
#> "some content\nmore content more on the same line"

Các gói và việc kèm (include) file

Các gói (package) giúp ta mở rộng tính năng của thư viện chuẩn Julia.

# Có thể bạn sẽ không muốn chạy cả file này, vì các lệnh Pkg có thể 
# sẽ chạy rất lâu mới xong.
using Pkg

# liệt kê tất cả các gói hiện có:
#Pkg.available()

# cài đặt một gói (chẳng hạn Calculus) cùng tất cả thứ đi kèm theo nó:
Pkg.add("Calculus")

# để liệt kê tất cả những gói đã cài đặt 
Pkg.installed()

# để cập nhật tất cả những gói lên đến phiên bản mới nhất của chúng 
Pkg.update()

# để sử dụng một gói:
using Calculus
# sẽ nhập vào tất cả các hàm có trong gói đó vào không gian tên (namespace) hiện thời, 
# nhờ đó ta có thể gọi:
derivative(x -> sin(x), 1.0)
# mà không cần phải chỉ định tên gói chứa hàm này.

import Calculus
# sẽ cho phép bạn chỉ định cụ thể là hàm được gọi tương ứng với gói nào 
Calculus.derivative(x -> cos(x), 1.0)

# Dùng `import` sẽ đặc biệt hữu ích nếu có sự xuong đột tên hàm / tên kiểu 
# giữa các gói.

Vẽ đồ thị

Việc vẽ đồ thị trong Julia chỉ thực hiện được bằng các gói phụ trợ. Ví dụ về một số gói chính được trình bày dưới đây

Plots

Gói Plots.jl được cài đặt qua lệnh

Pkg.add("Plots"); Pkg.add("GR");

using Plots

# vẽ đồ thị cho vài số liệu 
plot([cumsum(rand(500) .- 0.5), cumsum(rand(500) .- 0.5)])

# lưu bản vẽ đồ thị hiện tại 
savefig("plots.svg")
# .eps, .pdf, & .png cũng là các đuôi file được hỗ trợ 
# nhưng ở đây ta dùng svg vì nó bảo tồn tỉ lệ bề ngang và chiều cao đã nêu trên 
plots.svg

DataFrames

Gói DataFrames.jl cho ta công cụ làm việc với dữ liệu dạng bảng dữ liệu.

File iris.csv trong ví dụ này có thể lấy về từ github.

Bạn có thể cũng cần đến gói CSV.jl để đọc dữ liệu từ file CSV.

using DataFrames
showln(x) = (show(x); println())
# TODO: cần thêm đường link đến tài liệu 

# Một DataFrame là một cơ sở dữ liệu lưu trong bộ nhớ 
df = DataFrame(A = [1, 2], B = [ℯ, π], C = ["xx", "xy"])
showln(df)
#> 2×3 DataFrames.DataFrame
#> │ Row │ A     │ B       │ C      │
#> │     │ Int64 │ Float64 │ String │
#> ├─────┼───────┼─────────┼────────┤
#> │ 1   │ 1     │ 2.71828 │ xx     │
#> │ 2   │ 2     │ 3.14159 │ xy     │

# Các cột của một DataFrame có thể được gán chỉ số là các số hoặc tên gọi 
showln(df[!, 1])
#> [1, 2]
showln(df[!, :A])
#> [1, 2]

showln(df[!, 2])
#> [2.71828, 3.14159]
showln(df[!, :B])
#> [2.71828, 3.14159]

showln(df[!, 3])
#> ["xx", "xy"]
showln(df[!, :C])
#> ["xx", "xy"]

# Các hàng của một DataFrame có thể được đánh chỉ số chỉ dùng số:
showln(df[1, :])
#> DataFrameRow
#> │ Row │ A     │ B       │ C      │
#> │     │ Int64 │ Float64 │ String │
#> ├─────┼───────┼─────────┼────────┤
#> │ 1   │ 1     │ 2.71828 │ xx     │
showln(df[1:2, :])
#> 2×3 DataFrames.DataFrame
#> │ Row │ A     │ B       │ C      │
#> │     │ Int64 │ Float64 │ String │
#> ├─────┼───────┼─────────┼────────┤
#> │ 1   │ 1     │ 2.71828 │ xx     │
#> │ 2   │ 2     │ 3.14159 │ xy     │

# Nhập dữ liệu vào trong DataFrame
# --------------------------------

using CSV

# DataFrame có thể được nạp từ file CSV bằng cách dùng CSV.read()
iris = CSV.read("iris.csv")

# Bộ dữ liệu iris (cùng nhiệu bộ khác) có thể được lấy bằng cách 
using RData, RDatasets
iris = dataset("datasets","iris")

# Bạn có thể trực tiếp nhập từ file .rda của ngôn ngữ lập trình R với
# mydf = load("path/to/your/df.rda")["name_of_df"], ví dụ 
diamonds = load(joinpath(dirname(pathof(RDatasets)),"..","data","ggplot2","diamonds.rda"))["diamonds"]

# Hiển thị DataFrame
# ------------------

# Kiểm tra tên và kiểu dữ liệu của từng cột trong DataFrame mới 
showln(names(iris))
#> Symbol[:SepalLength, :SepalWidth, :PetalLength, :PetalWidth, :Species]
showln(eltypes(iris))
#> DataType[Float64, Float64, Float64, Float64, CategoricalString{UInt8}]

# Phân chia tập con cho DataFrame để chỉ bao gồm các hàng cho một loài 
showln(iris[iris[!, :Species] .== "setosa", :])
#> 50×5 DataFrames.DataFrame
#> │ Row │ SepalLength │ SepalWidth │ PetalLength │ PetalWidth │ Species      │
#> │     │ Float64     │ Float64    │ Float64     │ Float64    │ Categorical… │
#> ├─────┼─────────────┼────────────┼─────────────┼────────────┼──────────────┤
#> │ 1   │ 5.1         │ 3.5        │ 1.4         │ 0.2        │ setosa       │
#> │ 2   │ 4.9         │ 3.0        │ 1.4         │ 0.2        │ setosa       │
#> │ 3   │ 4.7         │ 3.2        │ 1.3         │ 0.2        │ setosa       │
#> │ 4   │ 4.6         │ 3.1        │ 1.5         │ 0.2        │ setosa       │
#> │ 5   │ 5.0         │ 3.6        │ 1.4         │ 0.2        │ setosa       │
#> │ 6   │ 5.4         │ 3.9        │ 1.7         │ 0.4        │ setosa       │
#> │ 7   │ 4.6         │ 3.4        │ 1.4         │ 0.3        │ setosa       │
#> ⋮
#> │ 43  │ 4.4         │ 3.2        │ 1.3         │ 0.2        │ setosa       │
#> │ 44  │ 5.0         │ 3.5        │ 1.6         │ 0.6        │ setosa       │
#> │ 45  │ 5.1         │ 3.8        │ 1.9         │ 0.4        │ setosa       │
#> │ 46  │ 4.8         │ 3.0        │ 1.4         │ 0.3        │ setosa       │
#> │ 47  │ 5.1         │ 3.8        │ 1.6         │ 0.2        │ setosa       │
#> │ 48  │ 4.6         │ 3.2        │ 1.4         │ 0.2        │ setosa       │
#> │ 49  │ 5.3         │ 3.7        │ 1.5         │ 0.2        │ setosa       │
#> │ 50  │ 5.0         │ 3.3        │ 1.4         │ 0.2        │ setosa       │

# Đếm số hàng dữ liệu cho từng loài 
showln(by(iris, :Species, df -> size(df, 1)))
#> 3×2 DataFrames.DataFrame
#> │ Row │ Species      │ x1    │
#> │     │ Categorical… │ Int64 │
#> ├─────┼──────────────┼───────┤
#> │ 1   │ setosa       │ 50    │
#> │ 2   │ versicolor   │ 50    │
#> │ 3   │ virginica    │ 50    │

# Xử lý dữ liệu theo từng cột một 
iris[!, :SepalLength] = round.(Integer, iris[!, :SepalLength])
iris[!, :SepalWidth] = round.(Integer, iris[!, :SepalWidth])


# Lập bảng dữ liệu tương ứng với các cột đã xử lý để nhìn thấy các "cụm" (cluster)
tabulated = by(
    iris,
    [:Species, :SepalLength, :SepalWidth],
    df -> size(df, 1)
)
showln(tabulated)
#> 18×4 DataFrames.DataFrame
#> │ Row │ Species      │ SepalLength │ SepalWidth │ x1    │
#> │     │ Categorical… │ Int64       │ Int64      │ Int64 │
#> ├─────┼──────────────┼─────────────┼────────────┼───────┤
#> │ 1   │ setosa       │ 5           │ 4          │ 17    │
#> │ 2   │ setosa       │ 5           │ 3          │ 23    │
#> │ 3   │ setosa       │ 4           │ 3          │ 4     │
#> │ 4   │ setosa       │ 6           │ 4          │ 5     │
#> │ 5   │ setosa       │ 4           │ 2          │ 1     │
#> │ 6   │ versicolor   │ 7           │ 3          │ 8     │
#> │ 7   │ versicolor   │ 6           │ 3          │ 27    │
#> ⋮
#> │ 11  │ virginica    │ 6           │ 3          │ 24    │
#> │ 12  │ virginica    │ 7           │ 3          │ 14    │
#> │ 13  │ virginica    │ 8           │ 3          │ 4     │
#> │ 14  │ virginica    │ 5           │ 2          │ 1     │
#> │ 15  │ virginica    │ 7           │ 2          │ 1     │
#> │ 16  │ virginica    │ 7           │ 4          │ 1     │
#> │ 17  │ virginica    │ 6           │ 2          │ 3     │
#> │ 18  │ virginica    │ 8           │ 4          │ 2     │

# Bạn có thể lập một dataframe có phân nhóm như sau:
gdf = groupby(iris,[:Species, :SepalLength, :SepalWidth])

# rồi lặp qua bảng này
for idf in gdf
    println(size(idf,1))
end

# Thêm / bớt các cột
# ------------------

# insert!(df::DataFrame,index::Int64,item::AbstractArray{T,1},name::Symbol)
# thêm các số ngẫu nhiên ở cột thứ 5:
insertcols!(iris, 5, :randCol => rand(nrow(iris)))

# xóa cột này đi
select!(iris, Not(:randCol))

Bình luận về bài viết này

Filed under Tin học

Think Stats II – chương 1

Phân tích dữ liệu khám phá

Dịch từ cuốn Think Stats: Exploratory Data Analysis in Python của Allen B. Downey, NXB Green Tea Press. Sách điện tử được phát hành miễn phí theo giấy phép: Creative Commons Attribution-NonCommercial 4.0 Unported License. Trong quá trình phân phối bạn nên ghi rõ nguồn gốc cuốn sách.

Trở về Mục lục cuốn sách

Luận điểm của cuốn sách này là dữ liệu kết hợp với các phương pháp thực dụng sẽ trả lời được các câu hỏi và dẫn dắt những quyết định trong điều kiện không chắc chắn.

Chẳng hạn, tôi xin nêu một trường hợp cụ thể đặt ra từ một câu hỏi mà tôi nghe được khi tôi cùng vợ đang chờ sinh con đầu: liệu những đứa trẻ đầu lòng có xu hướng chào đời chậm hay không? Tiếp tục đọc

2 bình luận

Filed under Think Stats, Tin học

Chương 6: Xuất dữ liệu

Trở về Mục lục cuốn sách

Giới thiệu

Cuốn sách của Mark Monmonier với tựa đề How to Lie with Maps (Làm thế nào để lừa dối bằng những tấm bản đồ), đã vạch trần cách mà những cá nhân và tổ chức cố ý làm biến dạng những địa vật trên bản đồ một cách quá đáng để lừa dối. Khái niệm bao trùm cuốn sách này là tất cả bản đồ đều nói dối—ở một mức độ nhất định. Điều đó có thật. Như bạn đã đọc trong Chương 3, các phép chiếu đều gây nên biến đổi hình dạng, diện tích, khoảng cách, và phương hướng. Ngoài ra, mọi bản đồ đều đơn giản hóa thế giới thực và do đó đã lừa dối bằng cách lược bỏ. Các biểu tượng trên bản đồ phóng đại hoặc giảm nhỏ kích thước của địa vật. Tất cả điều này đều có thể được coi là lừa dối. Bây giờ, trước khi bạn ngừng đọc và vứt bỏ những tờ bản đồ như thứ phù phiếm, thì hãy nhớ rằng tất cả những mô hình của thực tại (tranh vẽ, văn chương, toán học, hình chụ) đều là trừu tượng hóa và do đó đều lừa dối ở mức độ nhất định; và nhờ sự lược bớt cùng trừu tượng hóa đó giúp cho việc giao tiếp trở nên thuận lợi, dễ hiểu hơn. Nói đơn giản, bản đồ trợ giúp việc chuyển tải thông tin bằng cách nhấn mạnh vị trí của địa vật (và bỏ qua nhiều đieạ vật khác) để phác họa những dạng mẫu trong không gian. Như Monmonier đã viết, “Một tấm bản đồ tốt cho ta biết nhiều điều dối trá vô hại nho nhỏ; nó kìm hãm sự thật để giúp người xem thấy được điều cần phải thấy” (1996, tr. 25).

Tiếp tục đọc

1 bình luận

Filed under Commons

Chương 6: Lập thiết bị đo đạc Trái đất: Khoa học môi trường và mạng lưới đầu đo thế hệ mới

Trở về Mục lục cuốn sách

Michael Lehning, Nicholas Dawes, Mathias Bavay | WSL Institute for Snow and Avalanche Research SLF
Marc Parlange | École Polytechnique Fédérale de Lausanne
Suman Nath, Feng Zhao | Microsoft Research

Những thử thách liên quan đến môi trường rộng khắp cùng nhận thức càng tăng về biến đổi khí hậu toàn cầu đang cho thấy một nhu cầu cấp thiết đối với các nhà khoa học môi trường về việc tiến hành nghiên cứu khoa học theo cách mới, tốt hơn. Các hệ thống quan trắc môi trường cỡ lớn sẵn có, với độ phân giải không-thời gian rất thưa, không chỉ đắt mà còn không thể chỉ ra những mối tương tác phức tạp giữa các thành phần khí quyển và mặt đất với đủ độ chuẩn xác để tạo thành các mô hình hệ thống môi trường chính xác. Tiếp tục đọc

1 bình luận

Filed under Mẫu hình IV, Tin học

Chương 5: Kéo bầu trời đêm lại gần hơn: Khám phá từ dòng lũ dữ liệu

Trở về Mục lục cuốn sách

Alyssa A. Goodman | Harvard University
Curtis G. Wong | Microsoft Research

Trong suốt lịch sử, các nhà thiên văn đã quen với dữ liệu đến từ bầu trời. Nhưng các khả năng tương đối mới của chúng ta cho phép lưu trữ dữ liệu bầu trời vào trong các “đám mây” mở ra những phương pháp mới và thú vị để truy cập, phân phối, sử dụng và phân tích dữ liệu, cả trong nghiên cứu lẫn giáo dục. Ở đây ta xét đến ba câu hỏi có liên quan lẫn nhau: (1) Những xu hướng nào mà ta đã và sắp thấy về mức độ tăng trưởng của việc thu thập dữ liệu từ kính viễn vọng? (2) Liệu ta sẽ có lời giải nào cho thử thách ngày một lớn lên của việc tìm thấy cây kim điển hình trong đống rơm dữ liệu này nhằm tiến hành khám phá khoa học? (3) Những vận hội nào ta sẽ nắm được trong tương lai xét về phân tích tính toán và hiển thị số liệu? Tiếp tục đọc

1 bình luận

Filed under Mẫu hình IV

Chương 3: Định nghĩa lại sinh thái học có sử dụng dữ liệu

Trở về Mục lục cuốn sách

James R. Hunt | University of California, Berkeley and the Berkeley Water Center
Dennis D. Baldocchi | University of California, Berkeley
Catharine van Ingen | Microsoft Research

Sinh thái học là ngành nghiên cứu về sự sống và tương tác của nó với môi trường vật lý xung quanh. Vì tình hình biến đổi khí hậu yêu cầu sự thích nghi nhanh chóng, nên các công cụ phân tích mới đóng vai trò thiết yếu để định lượng những thay đổi đó trong số những biến động tự nhiên vốn có. Sinh thái là ngành khoa học trong đó nghiên cứu thường được thực hiện bởi nhóm nhỏ các cá nhân, với dữ liệu ghi chép trong sổ tay. Nhưng ngày nay các nghiên cứu tổng hợp cỡ lớn đang được nỗ lực thực hiện bởi sự hợp tác giữa hàng trăm nhà khoa học. Những nỗ lực lớn hơn này là rất cần thiết vì hiện giờ có hai sự phát triển: một là khoa học được thực hiện bằng cách nào, và hai là những câu hỏi về quản lý tài nguyên được đặt ra. Dù những nghiên cứu tổng hợp có sự hợp tác vẫn còn đang trong giai đoạn hình thành nhưng tầm quan trọng ngày càng tăng của chúng đã rõ ràng. Sự hỗ trợ của máy tính luôn gắn liền với những hình thức hợp tác như vậy và là then chốt đối với quá trình nghiên cứu. Tiếp tục đọc

1 bình luận

Filed under Mẫu hình IV

Chương 2. Ngành khoa học mới bắt nguồn từ những ứng dụng trong lĩnh vực môi trường

Trở về Mục lục cuốn sách

Jeff Dozier | University of California, Santa Barbara
William B. Gail | Microsoft

Khoa học về Trái đất và môi trường đã trưởng thành qua hai giai đoạn chính và đang bước vào giai đoạn thứ ba. Trong giai đoạn đầu tiên, vốn đã kết thúc cách đây hai thập kỉ, khoa học Trái đất và môi trường đa phần là mang tính chuyên môn và tập trung vào việc phát triển kiến thức về địa chất, hóa học khí quyển, hệ sinh thái, và các lĩnh vực khác của hệ Trái đất. Đến thập niên 1980, cộng đồng khoa học đã nhận ra sự ràng buộc chặt chẽ giữa các chuyên môn này và bắt đầu nghiên cứu chúng như những thành tố của một hệ thống đơn nhất. Trong suốt giai đoạn thứ hai này, mẫu hình của khoa học hệ thống Trái đất đã xuất hiện. Đi cùng nó là khả năng hiểu được các hiện tượng phức tạp, có tính hệ thống như biến đổi khí hậu, vốn kết nối giữa các khái niệm về khoa học khí quyển, sinh học, và hành vi loài người. Điều cốt yếu để nghiên cứu các hệ thống tương tác trên Trái đất là khả năng tiếp nhận, xử lý, và làm các dữ liệu từ vệ tinh trở nên sẵn có; và đồng thời, các mô hình mới đã được xây dựng để thể hiện những ý tưởng đang phát triển của chúng ta về các quá trình phức tạp bên trong hệ thống Trái đất đầy biến động [1]. Tiếp tục đọc

1 bình luận

Filed under Mẫu hình IV, Sách

Chương 1: Định luật Gray: Tính toán khoa học lấy dữ liệu làm trung tâm

Trở về Mục lục cuốn sách

Alexander S. Szalay | The Johns Hopkins University
José A. Blakeley | Microsoft

Sự bùng nổ dữ liệu khoa học đã tạo ra một thử thách lớn đối với các dự án khoa học hiện đại. Với những tập hợp dữ liệu vượt ngoài phạm vi hàng chục terabyte, các nhà khoa học không có những giải pháp sẵn có nào để quản trị và xử lý dữ liệu ngay được [1]. Các dự án thành công đến giờ đều bố trí kết hợp những tập tin rời và cơ sở dữ liệu [2]. Tuy nhiên, phần lớn các giải pháp này đều được chỉnh lại cho từng dự án cụ thể và không thể dễ dàng khái quát hóa hay dãn ra để phù hợp với các thí nghiệm thế hệ mới được. Hơn nữa, các kiến trúc máy tính hiện đại ngày càng mất cân đối; khoảng cách về độ trễ giữa các bộ vi xử lý nhiều lõi với các ổ cứng cơ học càng nới rộng theo từng năm, làm cho thử thách đối với tính toán thiên về dữ liệu càng khó được đón nhận [3]. Điều mà ta cần là một phương pháp tổng quát và có hệ thống để giải quyết các vấn đề này với một kiến trúc mà có thể điều chỉnh trong tương lai. Tiếp tục đọc

1 bình luận

Filed under Mẫu hình IV

Phần I: Trái đất và môi trường

Trở về Mục lục cuốn sách

Trái đất & Môi trường

Lời giới thiệu

Dan Fay | Microsoft Research

Sự thay đổi là không thể tránh khỏi—vũ trụ nở rộng, giới tự nhiên tiến hóa và phát triển, và vì vậy những công cụ khoa học và kĩ thuật ta dùng cũng phải phát triển theo, để đáp ứng được công cuộc truy tìm không khoan nhượng những kiến thức khoa học sâu xa hơn về không gian, Trái đất, và môi trường. Vận hội và thử thách đặt ra là rất nhiều. Những công nghệ tính toán mới như điện toán đám mây và bộ vi xử lý nhiều lõi, dưới hình thức chung, đều không đủ cung cấp một giải pháp tổng thể. Nhưng sự áp dụng đúng thời điểm và hiệu quả của những công nghệ như vậy có thể giúp ta có bước tiến đáng kể về tầm hiểu biết đối với thế giới, bao gồm các thử thách về môi trường, và cách thức ứng phó với chúng. Tiếp tục đọc

1 bình luận

Filed under Mẫu hình IV