Below is my MWE. I do not know why I am having the below error though I am defining it at the beginning?
function curMatRLC(NodeVoltage, dt)
return s = ones(3*5) - dt;
return s = ones(3*5) + dt;
NodeVoltage = zeros(3,5);
A_Mat = ones(3*5,3*5);
I_Mat = ones(3*5);
global iter = 0;
for t in 0:1e-6:0.03
global iter += 1;
I_Mat[1:3*5] = curMatRLC(NodeVoltage,dt);
V_Mat = lu(A_Mat) \ I_Mat;
NodeVoltage = reshape(V_Mat[1:3*5], 3, :);
ERROR: LoadError: UndefVarError: NodeVoltage not defined
 macro expansion
If you are ever benchmarking, then you should never have the global identifier anywhere in sight. Put everything in a function (taking A_mat and I_mat as inputs, and tell call it as @btime my_function($A_mat, $I_mat)
Global variables are not in local scope without the global keyword. See Scope of Variables · The Julia Language. Adding the line global NodeVoltage to your innermost for loop should remove the error. However, it is better to write a function for that part of the code and pass NodeVoltage to that function. Then you won’t have to worry about scope and your code will be faster.
Reading from global variables, is always allowed, but re-assigning them is only allowed (if you explicitly declared them as global. (Note that I_Mat[1:3*5] = ... is not re-assigning I_Mat itself, but rather is mutating the contents of I_Mat.)
Your I_Mat is a Vector which is a type of mutable container meaning you can change what is held inside of I_Mat. When you write I_Mat[1:3*5] = new_value the values stored at those locations are changed in place (mutated). Whereas, if you write I_Mat = new_value, a new location in memory is allocated and assigned the name I_Mat (re-assignment). The difference is likely not important for you at this stage as long as you avoid global variables.
1- So is it always good to use indexes for the elements of vector (or matrix) as in I_Mat[1:3*5] = new_value, to avoid re-assignment?
2- After this new assignment of I_Mat = new_value , what will happen to the old location of I_Mat in memory? will be still occupied (but useless) of freed?
@Jeff_Emanuel The other variables that are bound to that array I_Mat are actually bound to the name not location, correct? So, by using the re-assignment, these variable will be bound to the name of the re-assignment, right?
If not right, could you please give me an example?
I updated your MWE to illustrate the general form of what I was describing above. I chose not to mutate for clarity. You may want to mutate if speed is more important.
using LinearAlgebra, BenchmarkTools
function curMatRLC(NodeVoltage, dt)
return s = ones(3*5) .- dt;
return s = ones(3*5) .+ dt;
function march!(NodeVoltage, A_Mat)
dt = 1e-6
for t in 0:dt:0.03
local I_Mat = curMatRLC(NodeVoltage, dt)
local V_Mat = lu(A_Mat) \ I_Mat
NodeVoltage = reshape(V_Mat, 3, :)
return NodeVoltage, A_Mat, I_Mat, V_Mat
NodeVoltage = zeros(3,5)
A_Mat = rand(3*5, 3*5)
(NodeVoltage, A_Mat, I_Mat, V_Mat) = march!(NodeVoltage, A_Mat)
@btime march!($NodeVoltage, $A_Mat)
Below are some issues I encountered getting your code to run with some explanations that you may find helpful:
dt wasn’t previously defined. I defined it as a scalar, so I could use it in the definition of t, but then I had to add a broadcasting . to the addition inside curMatRLC.
The result of curMatRLC doesn’t change with time right now. I assume you will need to pass another variable to it to represent whatever ones(3*5) is supposed to be, so that s changes.
The V_Mat calculation gave me an error because everything was 1’s, so I had to change A_Mat to be random numbers.
Scope became an issue again when returning values from my function since I_Mat and V_Mat are only defined inside the for loop. I added the local keyword to fix this. If you care about the values before the end time though, you probably want to define a vector to store your results at every timestep outside of the loop and then update the elements of that vector in the loop instead of using local.