אוניברסיטת בן גוריון. המחלקה למדעי המחשב. חישוב מדעי בJulia בקורס זה נתנסה בכלים ואלגוריתמים להתמודדות עם משימות של חישובים מדעיים בעזרת מחשב. כלים אלה שימושיים בתחומים מגוונים כגון עיבוד תמונה, חישובית, סטטיסטיקה,,פיסיקה/כימיה/ביולוגיה ראייה ממוחשבת, גרפיקה כלכלה חישובית ועוד. שפת הקורס הרשמית היא,Julia שהיא שפה חדשה יחסית המיועדת במיוחד לנושא החישוב המדעי ומאוד צוברת תאוצה בקהילה המדעית. השפה היא חינמית ודומה מאוד לסביבת העבודה.MATLAB ניתן לעבוד בקורס עם כל שפה אחרת SciLab.MATLAB, Python, Octave, Java, C/C++, C#, תמיכה תינתן בעיקר עבור MATLAB ו- Julia.
ניתן להוריד את Julia ב: סביבת הרצה ידידותית לווינדוס )לעבודה עם ישנה סביבה שנקראת "דיבאגר" http://julialang.org/ :)notepad++ https://conemu.github.io/ editor כמו Juno לעבודה "נוחה" עם http://junolab.org/ Julia https://github.com/keno/gallium.jl
מבני נתונים: בניגוד לmatlab, ב- Julia מגדירים טיפוסים, ואם לא מגדירים אותם הטיפוסים נקבעים תוך כדי ריצה. מבנה הנתונים העיקרי הוא וקטור )מטיפוס מסוים( או מטריצה. דוגמאות: וקטור: Array{Type,n} וקטור שורה )מטריצה julia> a=[0.2;7;11;5] 4-element Array{Float64,1}: 0.2 7.0 11.0 5.0 julia> a=[0.2 7 11 5] 1x4 Array{Float64,2}: 0.2 7.0 11.0 5.0 Array{Type,2} )1X4
מטריצה 3X3: ה"חוק": רווח למעבר עמודה. נקודה-פסיק למעבר שורה. במקרה של הגדרה לא חוקית בביצוע השורה תהיה הודעת שגיאה julia> A=[3 4 5; 4 7 9; 2 6 7] 3x3 Array{Int64,2}: 3 4 5 4 7 9 2 6 7 julia> A=[3 4 5; 4 7 9; 2 6] ERROR: ArgumentError: argument count does not match specified shape (expected 9, got 8) in hvcat at abstractarray.jl:962 n -יה )tuple( - בשימוש בעיקר בערכי החזרה של מספר משתנים מפונקציות. julia> A = (3,4,5) (3,4,5) julia> A = (3,4,"ABC") (3,4,"ABC")
אופרטור :"a:b:c" ניתן להגדיר וקטורים של סדרות המתחילות מ- a, מבצעות קפיצות של b ומסתיימות ב- c. בjulia הוקטור נשמר באופן ראשוני כשלשה, וניתן להמיר אותו למערך. )מאוד שימושי בעבודה עם אינדקסים, ובדוגמא האחרונה - ליצור "רשתות" לפונקציות( julia> 1:5 1:5 julia> 1:3:5 1:3:4 julia> collect ) 1:3:5( 2-element Array{Int64,1}: 1 4 julia> collect)1:-3:-10) 6-element Array{Int64,1}: 1-2 -5-8 julia> collect ) 0:0.25:1( 5-element Array{Float64,1}: 0.0 0.25 0.5 0.75 1.0
julia> A=[3 4 5; 4 7 9; 2 6 7] 3 3 Array{Int64,2}: 3 4 5 4 7 9 2 6 7 הוצאת נתונים מתוך מטריצות: אינדקסים במטלב מתחילים מ- 1 ולא מ- 0 julia> A[1:2,2:3] 2 2 Array{Int64,2}: 4 5 7 9 julia> A[1,[1,3]] 2-element Array{Int64,1}: 3 5
julia> A' 3 3 Array{Int64,2}: 3 4 2 4 7 6 5 9 7 julia> s = "Hellow World" "Hellow World" שחלוף :)transpose( מערך של :)string( chars julia> typeof(s) String
rand,.ones, eye, zeros פעולות על מבני נתונים: מטריצות אלמנטריות )משמשות גם להקצאת זיכרון(:.randn ישנן גם julia> ones(3) 3-element Array{Float64,1}: 1.0 1.0 1.0 julia> ones(3,3) 3 3 Array{Float64,2}: 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 julia> 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 julia> zeros(3,5) 3 5 Array{Float64,2}: 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 julia> zeros(int64,3,5) 3 5 Array{Int64,2}: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 julia> rand(float32,2,3) 2 3 Array{Float32,2}: 0.226422 0.203547 0.52014 0.981852 0.390658 0.663606
פעולות חיבור/חיסור: מתבצעות "איבר-איבר" julia> A = ones(3,3); B = eye(3); julia> A+B 3 3 Array{Float64,2}: 2.0 1.0 1.0 1.0 2.0 1.0 1.0 1.0 2.0
פעולות כפל/חילוק/חזקה: אילו הם פעולות "מטריציות" לפי אלגברה ליניארית גדלים צריכים להתאים לפי אלגברה ליניארית. julia> A*B # B is identity, therefore answer is A. 3 3 Array{Float64,2}: 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 julia> A^2 # same as A*A 3 3 Array{Float64,2}: 3.0 3.0 3.0 3.0 3.0 3.0 3.0 3.0 3.0 julia> B\A # same as inv(b)*a see later. 3 3 Array{Float64,2}: 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
פעולות כפל/חילוק/חזקה "איבר-איבר" גדלים צריכים להיות זהים. julia> A.*B # B is identity, A is ones. Therefore answer is B. 3 3 Array{Float64,2}: 1.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0 julia> x = 0:0.25:1 חישוב פונקציות על מערכים: julia> f = sin(x) 5-element Array{Float64,1}: 0.0 0.247404 0.479426 0.681639 0.841471 julia> f = sin(x).*cos(x) 5-element Array{Float64,1}: 0.0 0.239713 0.420735 0.498747 0.454649
julia> size(zeros(3,5)) (3,5) פעולות שימושיות: :isempty, sum, mean, max, min, size julia> maximum([4,5,6]) 6 julia> maximum([4 5 6;7 8 9]) 9 julia> maximum([4 5 6;7 8 9],1) 1 3 Array{Int64,2}: 7 8 9 julia> maximum([4 5 6;7 8 9],2) 2 1 Array{Int64,2}: 6 9
A פתרון מערכת משוואות ליניאריות )אופרטור חילוק מטריצות( 3x 5y 44 3 5 x1 44 1 x A b 2x y 27 2 1 x 2 27 האופציה השנייה היא הטובה יותר: julia> A=[3-5 ; 2 1];b=[-44 ; 27]; x b בג'וליה ובמטלב ישנן 2 אופציות julia> s = inv(a)*b # inverts A and multiply more expensive. 2-element Array{Float64,1}: 7.0 13.0 julia> s = A\b # just calculates the result faster 2-element Array{Float64,1}: 7.0 13.0
# if sentence if i==1 statement; end # if-else if res(n,2) ~= 0 statement; else statement; end # if-elseif if (A > B) statement; elseif (A< B) statement; elseif ~A statement; else statement; end בקרת זרימה: משפטי תנאי:
# for loop for n=1:1:4 statement; end # while loop a = 4; fa=sin(a); b = 2; fb = sin(b); while a - b > 5 * eps x = (a+b)/2; fx = sin(x); if sign(fx) == sign(fa), a = x; fa=fx; break; else b = x; fb = fx; end end בקרת זרימה: לולאות:
הצגת פלט המספרים julia> println("a is: ",4.5) A is: 4.5 julia> @printf "%d is less than %f" 4.5 5.3 5 is less than 5.300000 julia> @printf "%d is less than %2.2f" 4.5 5.3 5 is less than 5.30 julia> @printf "%d is less than %2.2e" 4.5 5.3 5 is less than 5.30e+00
עבודה עם קבצים: בד כ לא נוח לעבוד בצורה אינטראקטיבית בלבד ל- session. session מאבדים את מה שקרה בין o קבצי ההפעלה של Julia הם עם סיומת.".jl" ניתן ליצור קובץ כזה לכתוב בו רשימת פקודות ולשמור אותו בשם מסוים. o include( myfile.jl ) כדי להפעיל קובץ הפקודות o הרצת הפקודות קוראת באותו האופן כאילו הורצו "ידנית". o ניתן באותו הקובץ להגדיר פונקציות, ולאחר מכן להריץ אותן o # myfile.jl: using SomePackage include( otherfiles.jl ); function foo(float64 a) # define your function here end # demonstrate foo: println(foo(5.4));
הגדרת פונקציות: במטלאב - קובץ שבו כתובה פונקציה צריך להיות בעל שם זהה לשם הפונקציה הראשית שלו, פונקציה אחת public והשאר.private בג'וליה, קובץ פשוט יכול להכיל מספר הגדרות של פונקציות, כולן. הפונקציות מקבלות קלט וכל הפעולות הנעשות בהם הם בבלוק לוקאלי בלבד כמו ב- C. ערך המשתנים בסיום התכנית הוא הערך המוחזר ע"י הפונקציה. בקובץ :pyt.jl """ function pyt(a::float64,b::float64) returns the hyotensus (yeter) in a right angle triangle according to Pythagoras theorem c is the hyotensus d and e are the two sharp angles """ function pyt(a::float64,b::float64) c = sqrt(a.^2+b.^2); d = atan(b/a); e = pi/2-d; return c,d,e; end
julia> @doc pyt function pyt(a::float64,b::float64) תיעוד העזרה: returns the hyotensus (yeter) in a right angle triangle according to Pythagoras theorem c is the hyotensus d and e are the two sharp angles ניתן לכתוב באותו קובץ פונקציות עזר נוספות באותו הקובץ. כולן יוגדרו. ניתן להבדיל בין מימושים ע"י טיפוסי ארגומנטים שונים. function calclength(a::float64,b::float64) L = sqrt(a^2 + b^2); return L; end function calclength(a::array{float64},b::array{float64}) L = sqrt(a.^2 + b.^2); return L; end
function calclength(a::array{float64},b::array{float64}) norm_func = (a,b)->sqrt(a.^2 + b.^2); L = norm_func(a,b); return L; end שימוש במצביעים לפונקציות: function calclength(a::array{float64},b::array{float64},norm_func::function) L = norm_func(a,b); return L; end
פקודות שימושיות: Writedlm,readdlm ניתן לשמור את המשתנים לקבצי טקסט. שימושי כאשר זמן ריצה של תכניות ארוך מאוד. עוד מידע ניתן למצוא ב http://docs.julialang.org/en/release-0.5/stdlib/io-network/.juliarc.jl ניקוי של מסך ה- console. CTR L קובץ חבוי המכיל רשימת פקודות שירוצו בטעינת ג'וליה: חבילות שימושיות: חלק מהפקודות של Julia ניתנות באמצעות חבילות )חינמיות( שמותקנות בנוסף. מתבצע ע"י Pkg.add( name ) חבילת :MAT חבילת פונקציות לשמירת קבצים מהסוג של מטלאב. חבילת :PyPlot חבילה לחיבור ציור גרפים מ- Python )דורשת התקנת Python.)anaconda החבילות שמותקנות נמצאות בספרייה.julia יש לטעון את החבילות באמצעות.using
כתיבת חבילות Modules כאשר רוצים "לעטוף" חבילת קוד משתמשים בmodule : טעינת הmodule תיעשה ע"י using )או שהמודול נמצא בספרייה,).julia כאשר צריך לוודא שהקבצים בPATH, ע"י: push!(load_path,path_string); module MyModule using Lib using BigLib: thing1, thing2 import Base.show importall OtherLib export MyType, foo type MyType x end bar(x) = 2x foo(a::mytype) = bar(a.x) + 1 show(io::io, a::mytype) = print(io, "MyType $(a.x)") include( otherfile.jl ) end
חישוב מקבילי ישנם שני סוגים חישוב מקבילי שבהם אנו משתמשים: חישוב מקבילי בזיכרון משותף process( אחד עם )threads ע"י.OMP חישוב מקבילי/מבוזר בזיכרון לא משותף בדר"כ מתבצע ע"י.MPI וגם בMATLAB, ניתן להשתמש רק בחישוב עם זיכרון לא משותף )נפתחים תהליכים.1.2 בJulia "עובדים" עם זיכרון משלהם(. אם לא נזהרים ניתן ליצור העתקים של הזיכרון אצל כל עובד. יש אפשרות ל- arrays.shared חישוב בזיכרון משותף ע"י OMP ניתן רק ע"י חיבור פונקציות הכתובות בשפה אחרת כגון C.
חישוב מקבילי ב- Julia ע"י הפקודה addprocs(n) ניתן לייצר n עובדים לוקאליים. או ע"י הרצת ג'וליה בצורה הבאה:.Julia p n דוגמא: julia -p 2 julia> r = remotecall(rand, 2, 2, 2) Future(2,1,3,Nullable{Any}()) julia> s = @spawnat 2 1.+ fetch(r) Future(2,1,6,Nullable{Any}()) julia> fetch(s) 2 2 Array{Float64,2}: 1.60401 1.50111 1.17457 1.15741
using PyPlot figure(); x=0:0.01:5; y=sin(x).*cos(50*x); plot(x,y) title("example plot") וויזואליזציה ציור גרפים/תמונות: :plot הקצאה של חלון ציור. הפונקציה הכי שימושית לציור גרפים היא Figure() # adds a title xlabel("x") # adds a title to the x axis ylabel("y=sin(x).*cos(50*x)")# adds a title to the y axis 1 Example plot 0.8 0.6 0.4 y=sin(x).*cos(50*x) 0.2 0-0.2-0.4-0.6-0.8-1 0 0.5 1 1.5 2 2.5 3 3.5 4 4.5 5 x
ציור כמה גרפים על אותה התמונה: figure(); x=0:0.01:5; subplot(1,3,1); # plots a line of 3 plots. Now we plot the first. y=sin(x).*cos(50*x); plot(x,y,"-r"); # red line title("example plot 1"); xlabel("x"); ylabel("y=sin(x).*cos(50*x)"); subplot(1,3,2); # Now we plot the second. y=exp(x); plot(x,y,":k",linewidth=2); # thick line title("example plot 2") xlabel("x") ylabel("exp(x) ") subplot(1,3,3); # Now we plot the third. y=log(x); plot(x,y, "-.b",linewidth=2); # title("example plot 3") xlabel("x") ylabel("ln(x) ")
1 Example plot 1 150 Example plot 2 2 Example plot 3 1 y=sin(x).*cos(50*x) 0.5 0-0.5 exp(x) 100 50 ln(x) 0-1 -2-3 -4-1 0 1 2 3 4 5 x 0 0 1 2 3 4 5 x -5 0 1 2 3 4 5 x
ציור כמה גרפים "אחד על השני": figure(); x = 0:0.01:1; y=exp(x); plot(x,y, ":k",linewidth = 2); # thick line y=sin(x); plot(x,y, "-.r",linewidth=2); title("example multiple lines") xlabel("x") legend(("exp(x) ","sin(x) ")); 3 2.5 Example multiple lines exp(x) sin(x) 2 1.5 1 0.5 0 0 0.2 0.4 0.6 0.8 1 x