1


In [1]:
#Robert Driving Sonny Nav
function Axb(A::Array{Float64,2},b::Array{Float64,1})
  return A*b
end


Out[1]:
Axb (generic function with 1 method)

In [2]:
A = rand((2,2))
b = rand((2))


Out[2]:
2-element Array{Float64,1}:
 0.664424
 0.293108

In [3]:
print(Axb(A,b),A*b)


.7778711252014386
.751041934911207
.7778711252014386
.751041934911207

In [4]:
#Sonny driving, Robert Nav
function Axb_2(A::Array{Float64,2},b::Array{Float64,1})
    x = zeros(size(b))
    for i in 1:length(A[:,1])
        for j in 1:length(A[1,:])
            x[i] += A[i,j]*b[j]
        end
    end
    return x
end


Out[4]:
Axb_2 (generic function with 1 method)

In [5]:
print(Axb_2(A,b),A*b)


.7778711252014386
.751041934911207
.7778711252014386
.751041934911207

In [6]:
#Sonny driving, Robert Nav
function Axb_3(A::Array{Float64,2},b::Array{Float64,1})
    x = zeros(size(b))
    for j in 1:length(A[1,:])
        for i in 1:length(A[:,1])
            x[i] += A[i,j]*b[j]
        end
    end
    return x
end


Out[6]:
Axb_3 (generic function with 1 method)

In [7]:
print(Axb_3(A,b),A*b)


.7778711252014386
.751041934911207
.7778711252014386
.751041934911207

1d.

b will be faster because it is in column major form.

1e.

Should be about the same for small matrices as they will fit on the L1 cache so they will be qucik either way.


In [8]:
function testing_function(f1,f2,f3,dimension)
  A = rand((dimension,dimension))
  b = rand((dimension))
  println(dimension,"x",dimension, " Matrix")
  println("Function 1    Function 2    Function 3")
  println((@elapsed f1(A,b)),"      ",(@elapsed f2(A,b)),"      ",(@elapsed f2(A,b)))
  println()
end


Out[8]:
testing_function (generic function with 1 method)

In [9]:
testing_function(Axb,Axb_2,Axb_3,8)


8x8 Matrix
Function 1    Function 2    Function 3
5.856e-6      9.537e-6      2.273e-6


In [10]:
for i in [4,8,32,264,512,1024,1025,10000]
  testing_function(Axb,Axb_2,Axb_3,i)
end


4x4 Matrix
Function 1    Function 2    Function 3
5.037e-6      8.714e-6      2.281e-6

8x8 Matrix
Function 1    Function 2    Function 3
8.09e-6      4.729e-6      2.988e-6

32x32 Matrix
Function 1    Function 2    Function 3
2.728e-6      2.8385e-5      2.1947e-5

264x264 Matrix
Function 1    Function 2    Function 3
0.000339658      0.001088721      0.001148038

512x512 Matrix
Function 1    Function 2    Function 3
0.000504836      0.00347624      0.006173517

1024x1024 Matrix
Function 1    Function 2    Function 3
0.001708682      0.041160704      0.039387101

1025x1025 Matrix
Function 1    Function 2    Function 3
0.001048628      0.037675767      0.023529767

10000x10000 Matrix
Function 1    Function 2    Function 3
0.065427243      5.855805872      5.523546687

Ooopse we got our terminology mixed-up with or rows and columns. -R

Note the thrashing in the 1024 and 1025 cases. -S

2a.)

The use of the abstract type is sufficient since the lookup() function has an implicit capability to parse different table types. -S


In [11]:
#2b) 
#Sonny driving
#Pkg.add("Calculus")

In [12]:
include("CLASS_REPO/Astro585/Lab5/HW5_Q2_lookup_table.jl")


Out[12]:
lookup (generic function with 3 methods)

In [12]:
lookup_table = make_table_linear(x->tanh(x),0.,2.,10);

In [12]:
#2c)
#Sonny driving
using PyPlot
x = linspace(0.,2.,1000);
y1 = tanh(x);
y2 = lookup(lookup_table,x);
res = y2 - y1;
plot(x,y1,label="Function");
plot(x,y2,label="Lookup");
legend(loc="lower right");
#figure();
#plot(x,res,'o',label="Residuals")
#legend();



In [12]:
using PyPlot
plot(x,res,label="Residuals")
legend();


2c.)

Tada! It works pretty well. -S


In [13]:
#robert driving
println("Function ", (@elapsed tanh(x)))
println("lookup ", (@elapsed lookup(lookup_table,x)))


Warning: Possible conflict in library symbol dtrtri_
Warning: Possible conflict in library symbol dgetri_
Warning: Possible conflict in library symbol dgetrf_
Function 5.2298e-5
lookup 0.001251682

Why would anyone do that? So slowwwwwwwwww! -R


In [13]:
#I stole this from stack exchange -R
function fact(n)
    if n == 1
        n 
    else 
        n * fact(n-1) 
    end                                                                      
end;

In [14]:
function fn(x::Float64): 
  @assert x <= 20
  @assert x >= 1.0
  A = fact(iceil(x)) 
  x -= 1
  for i in 1:100
    x += 1/i
  end
  return A*tanh(x)/(sin(x) + cos(x))
end


Out[14]:
fn (generic function with 1 method)

In [14]:
LU1 = make_table_linear(x->fn(x),1.1,20.,100);

In [15]:
x = linspace(1.1,19.9,10000)
#robert driving
println("Function ", (@elapsed [fn(i) for i in x]))
println("lookup ", (@elapsed lookup(LU1,x)))


Function 0.028917098
lookup 0.016390423

The more absurd we made the function, eventally we got the lookup table to beat it, but it shows the idea -R


In [16]:
include("CLASS_REPO/Astro585/Lab5/HW5_Q2_ecc_anom.jl")


Out[16]:
decc_anom_dM (generic function with 1 method)

2d part 2 The Return of the Julia


In [16]:
#Sonny Driving
x = linspace(-2*pi,4*pi,1000);
ecc_1 = ecc_anom(x,0.25);
using PyPlot 
plot(x,ecc_1);
xlabel("Mean Anomaly");
ylabel("Eccentric Anomaly");


This would perform better than calculating a lot of eccentricity anomalies (there's a while statement in ecc_anom). -S


In [16]:
ecc_table1 = make_table_linear(x->ecc_anom(x,0.25),0.,2*pi,128);

In [16]:
#Sonny Driving
x = linspace(0.,2*pi,1000);
ecc_2 = ecc_anom(x,0.25);
using PyPlot 
plot(x,ecc_2);
plot(x,lookup(ecc_table1,x))
ylim(-7,7);
xlabel("Mean Anomaly");
ylabel("Eccentric Anomaly");


The artifacting has to be something from the interpolation process - otherwise, the ecc_anom call would also show it. -S


In [18]:
#Robert Driving
ecc_table2 = make_table_linear(x->ecc_anom(x,0.25),x->decc_anom_dM(x,0.25),0.,2*pi,128)


Out[18]:
lookup_table_linear_type([0.0,0.06594926834324932,0.13180330494829162,0.1974686520141046,0.26285531133600754,0.32787826188799074,0.39245874516739376,0.456525274597337,0.5200143477034695,0.5828708613683835  …  5.700314445811203,5.763170959476115,5.826660032582249,5.890726562012193,5.955307045291593,6.020329995843578,6.085716655165482,6.151382002231294,6.217236038836336,0.0],[1.0,1.0167637056158338,1.034073578811775,1.0519308413114592,1.0703358668807594,1.0892885054667514,1.108788428861808,1.1288354821115478,1.1494300263451658,1.1705732612732902  …  -2.3525060378415126,-2.268639906131681,-2.189788974769114,-2.1155888325507135,-2.045714513038787,-1.9798745790188708,-1.9178060404770738,-1.8592699928936012,-1.8040478911299431,1.0],0.0,6.283185307179586,128)

In [18]:
#Robert Driving
x = linspace(0.,2*pi,1000);
ecc_2 = ecc_anom(x,0.25);
using PyPlot 
plot(x,ecc_2);
plot(x,lookup(ecc_table2,x))
ylim(-2,7);
xlabel("Mean Anomaly");
ylabel("Eccentric Anomaly");



In [21]:
decc = [decc_anom_dM(i,0.25) for i in x ]


Out[21]:
1000-element Array{Any,1}:
  1.0    
  1.0021 
  1.00421
  1.00633
  1.00846
  1.01059
  1.01274
  1.01489
  1.01705
  1.01923
  1.02141
  1.02359
  1.02579
  ⋮      
 -1.82566
 -1.81871
 -1.81181
 -1.80496
 -1.79816
 -1.79141
 -1.78471
 -1.77806
 -1.77146
 -1.7649 
 -1.7584 
  1.0    

In [22]:
plot(x,decc)


Out[22]:
1-element Array{Any,1}:
 PyObject <matplotlib.lines.Line2D object at 0x110594e90>

In [ ]: