Hello!
I am trying to code Cramer’s rule from linear algebra in Julia. I am running into some variable behavior I don’t quite understand. Here’s the code (forgive the lack of “verbatim” I’m not sure how to format in discourse):
using LinearAlgebra
A = Matrix([1 4 7; 2 8 5; 3 6 9;])
if det(A) == 0
return “not invertible, cannot use Cramer’s Rule”
else
# set b = something
b = [-1; 0; 1]
m = size(A)[1]
x =
for k in 1:m
global x
global A
println(“matrix A”)
display(A)
An = A
An[:,k] = b
println(“Matrix An”)
display(An)
xn = det(An)/det(A)
x = push!(x,xn)
display(x)
end
end
I’m confused by the behavior of A. When I change An matrix A also changes. That’s not good! I tried looking up static variables in Julia but these don’t seem to work like Python.
Can anyone explain what’s going on here and how I fix it?
Gratefully, Brian
EDIT: I’ve fixed Cramer’s rule, but only … inelegantly. Really hoping to understand why setting An = A then changing An also changes A… I think this is called a pointer? Forgive me, I’m not experienced.
-
To format code wrap it between triple ticks:
```
at the beginning and at the end
```
Will look like this:
at the beginning and at the end
-
This is not aboout global variables. When you do An = A you are giving a new name (An) to the same object in memory as A. So when you modify one you modify the other one as well.
You want to do:
An = copy(A)
This behavior is mentioned for example in the second point of this list: Noteworthy Differences from other Languages · The Julia Language
By the way this works the same in python, maybe you were thinking Matlab?:
In [3]: a = [[1, 1, 1], [2, 2, 2]]
In [4]: a
Out[4]: [[1, 1, 1], [2, 2, 2]]
In [5]: a1 = a
In [6]: a1[1][1] = 5
In [7]: a1
Out[7]: [[1, 1, 1], [2, 5, 2]]
In [8]: a
Out[8]: [[1, 1, 1], [2, 5, 2]]
1 Like
As a previous Matlab user, it is strange to me that not copying is the default. I never want to rename a variable without copying it. Why would I want two different names for the same object?
One reason for me is typing convenience. Suppose I have a long-named struct long_named_struct
containing an array sparams
. If I pass the struct to a function, it may be more convenient to work with the array in the function as follows:
function func!(long_named_struct, x, y, ...)
sp = long_named_struct.sparams # Short local name for use in func!
...
end
1 Like