{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "#### Julia Tutorial: Vectors\n", "Vectors in Julia differ a bit from Matlab. \n", "In Matlab, everything is an array, including vectors (and even scalars). \n", "In Julia, there are distinct data types for scalars, vectors, rowvectors, and 1D arrays. \n", "This notebook illustrates the differences. \n", "Jeff Fessler, University of Michigan \n", "2017-07-24, original \n", "2020-08-05, Julia 1.5.0 \n", "2021-08-23, Julia 1.6.2 " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Scalars, Vectors, Arrays" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a = 4 # this is a scalar" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "b1 = [4] # this is a Vector with one element" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "b2 = reshape([4], 1, 1) # here is a 1×1 Array" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "b3 = reshape([4], 1, 1, 1) # here is a 1×1×1 Array" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a==b1, b1==b2, a==b2, b2==b3 # in Julia these all differ! (in Matlab they are the same)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Vectors and Transpose" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "c = [4 5 6] # this construction (with just spaces) makes a 1×3 Array" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "d = [4, 5, 6] # this construction (using commas) makes a 1D Vector" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "e = [4; 5; 6] # so does this construction, whereas in Matlab the \",\" and \";\" work differently" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "d' # the transpose of a Vector is slightly different than a 1×N array! This is subtle!" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "d' == c # nevertheless, the values are the same..." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "(d')' # Transposing back gives a vector again (not a N×1 array)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "d==e, d'==c, (c')'==d' # These are all true, as expected, despite the adjoint type." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "c==d, c==e, c'==d, (d')'==c' # These are all false." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "c * c' # \"inner product\" of a 1×3 Array with a 3×1 Array returns a 1×1 Array, not a scalar" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "d' * d # This inner product of an Adjoint Vector with a Vector returns a scalar" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "vec(c) # how to make a vector from an array" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "c[:] # Here is another way (but it uses more memory than vec)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Call by reference\n", "Julia uses call-by-reference (not value), like C/C++, unlike Matlab!" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "A = zeros(2); B = A; B[1] = 7; # B is the same \"pointer\" so this changes A\n", "@show A;" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "A = zeros(2); B = A .+ 2; B[1] = 7; # here B is different so this does not change A\n", "@show A;" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "A = B = zeros(2); B[1] = 7; # changes A because B and A point to same data\n", "@show A;" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "A = B = zeros(2); A[1] = 7; # changes B for the same reason\n", "@show B;" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To avoid this issue, one can use `copy`.\n", "It is only needed rarely though." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "A = zeros(2); B = copy(A); B[1] = 7; # B here uses different memory than A\n", "@show A; # here it is unchanged" ] } ], "metadata": { "jupytext": { "encoding": "# -*- coding: utf-8 -*-" }, "kernelspec": { "display_name": "Julia 1.6.2", "language": "julia", "name": "julia-1.6" } }, "nbformat": 4, "nbformat_minor": 4 }