306 lines
7.0 KiB
Plaintext
306 lines
7.0 KiB
Plaintext
{
|
||
"cells": [
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {
|
||
"collapsed": true
|
||
},
|
||
"source": [
|
||
"# Functions of Arrays\n",
|
||
"\n",
|
||
"This notebook illustrates how to apply a function to arrays. Another notebook focuses on matrix algebra."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Load Packages and Extra Functions"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 1,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"printyellow (generic function with 1 method)"
|
||
]
|
||
},
|
||
"execution_count": 1,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"using Printf\n",
|
||
"\n",
|
||
"include(\"jlFiles/printmat.jl\") #a function for prettier matrix printing"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"# Elementwise Functions of Arrays: Using Dot (.)\n",
|
||
"\n",
|
||
"Let `X` be an array, and `a` and `b` be scalars. Then, `y = fn.(X,a,b)` generates an array `y` where `y[i,j] = fn(X[i,j],a,b)`\n",
|
||
"\n",
|
||
"(You could achieve the same thing with ```map(xi->fn(xi,a,b),x)```.)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 2,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"fn (generic function with 1 method)"
|
||
]
|
||
},
|
||
"execution_count": 2,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"fn(x,a,b) = a/x + b #x has to be a scalar for this to work"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 3,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
" 110.000 60.000\n",
|
||
" Inf 20.000\n",
|
||
"\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"X = [1 2;\n",
|
||
" 0 10]\n",
|
||
"\n",
|
||
"printmat(fn.(X,100,10)) #notice the dot."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"# Looping over Columns or Rows\n",
|
||
"\n",
|
||
"Suppose you want to calculate the sum of each row of a matrix. The classical way of doing that is to loop and extract each row as `X[i,:]`\n",
|
||
"\n",
|
||
"Notice that instead of `sum(X[:,i])` it may be faster and save memory to do `sum(view(X,i,:))` because this avoids creating a new array of `X[:,i]`.\n",
|
||
"\n",
|
||
"Also, there is a direct way to loop over all rows by using `for r in eachrow(X)`. To also get the row number `i`, we use `for (i,row) in enumerate(eachrow(X))`. For looping over columns, use `eachcol()`."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 4,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"X:\n",
|
||
" 1 2 \n",
|
||
" 0 10 \n",
|
||
"\n",
|
||
"sum of each row:\n",
|
||
" 3.000\n",
|
||
" 10.000\n",
|
||
"\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"X = [1 2;\n",
|
||
" 0 10]\n",
|
||
"println(\"X:\")\n",
|
||
"printmat(X)\n",
|
||
"\n",
|
||
"m = size(X,1)\n",
|
||
"\n",
|
||
"z = zeros(m) #to fill with results, could here use zeros(Int,m)\n",
|
||
"for i = 1:m #loop over rows\n",
|
||
" z[i] = sum(X[i,:]) #or sum(view(X,i,:)) to save memory\n",
|
||
"end\n",
|
||
"println(\"sum of each row:\")\n",
|
||
"printmat(z)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 5,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"sum of each row:\n",
|
||
" 3.000\n",
|
||
" 10.000\n",
|
||
"\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"z = zeros(m) \n",
|
||
"for (i,row) in enumerate(eachrow(X)) #enumerate to get both index and value\n",
|
||
" z[i] = sum(row)\n",
|
||
"end\n",
|
||
"println(\"sum of each row:\")\n",
|
||
"printmat(z)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"# Functions with Built-in `dims` Argument\n",
|
||
"\n",
|
||
"May functions have a `dims` argument that allows you to avoid looping, for instance, `sum`."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 6,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
" 3 \n",
|
||
" 10 \n",
|
||
"\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"printmat(sum(X,dims=2))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"# Functions with Built-in `function` and `dims` Arguments (extra)\n",
|
||
"\n",
|
||
"Several functions allow you to also apply an elementwise function to `X` before doing the rest of the calculations, for instance, `any`, `all`, `sum`, `prod`, `maximum`, and `minimum`."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 7,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"2×1 Matrix{Int64}:\n",
|
||
" 5\n",
|
||
" 100"
|
||
]
|
||
},
|
||
"execution_count": 7,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"sum(abs2,X,dims=2) #same as sum(abs2.(X),dims=2) but faster"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"# Apply Your Own Function on Each Column: mapslices (extra)\n",
|
||
"\n",
|
||
"...or each row (or some other dimension)\n",
|
||
"\n",
|
||
"The `mapslices(fun,x,dims=1)` applies `fun(x[:,i])` to each column of a matrix `x`. This is an alternative to looping over the columns.\n",
|
||
"\n",
|
||
"The cell below illustrates this by calling a function which calculates the moving average of `x[t]` and `x[t-1]` for each column of a matrix `X`."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 8,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
" X (with 2 columns) and Y (MA(1) of X):\n",
|
||
" 1.000 101.000 NaN NaN\n",
|
||
" 2.000 102.000 1.500 101.500\n",
|
||
" 3.000 103.000 2.500 102.500\n",
|
||
" 4.000 104.000 3.500 103.500\n",
|
||
" 5.000 105.000 4.500 104.500\n",
|
||
"\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"function MovingAvg2(x) #moving average of t and t-1\n",
|
||
" T = length(x)\n",
|
||
" y = fill(NaN,T)\n",
|
||
" for t = 2:T\n",
|
||
" y[t] = (x[t] + x[t-1])/2\n",
|
||
" end\n",
|
||
" return y\n",
|
||
"end\n",
|
||
"\n",
|
||
"X = [1:5 101:105]\n",
|
||
"Y = mapslices(MovingAvg2,X,dims=1)\n",
|
||
"println(\" X (with 2 columns) and Y (MA(1) of X):\")\n",
|
||
"printmat([X Y])"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": []
|
||
}
|
||
],
|
||
"metadata": {
|
||
"@webio": {
|
||
"lastCommId": null,
|
||
"lastKernelId": null
|
||
},
|
||
"anaconda-cloud": {},
|
||
"kernelspec": {
|
||
"display_name": "Julia 1.6.1",
|
||
"language": "julia",
|
||
"name": "julia-1.6"
|
||
},
|
||
"language_info": {
|
||
"file_extension": ".jl",
|
||
"mimetype": "application/julia",
|
||
"name": "julia",
|
||
"version": "1.6.1"
|
||
}
|
||
},
|
||
"nbformat": 4,
|
||
"nbformat_minor": 1
|
||
}
|