iterating a function within itself

2 views (last 30 days)
Lewis Waswa
Lewis Waswa on 30 Aug 2023
Commented: Voss on 1 Sep 2023
Hey everyone. I have a function which performs adjustment based on 2 indices NPI and CPI as shown below.
[A,B,C,D,NPI,CPI]=Adjustingcode2(fdrpath1,sheetname,RepCondpath);
CPI and NPI are a 1 by 7 matrices. The optimal value in any of the index of CPI and NPI must be less than 1. So to do this, I need to iterate the function by itself conditionally - only stopping at the first instance where CPI and aNPI are <1. I have thus created an iterate function to do this as follows. However, the final values I obtain for the NPI are not less than 1. Anyone can point out where the problem is?
function [A1,B1,C1,D1,NPI_new,CPI_new] =CSS_iterate(fdrpath1,sheetname,RepCondpath)
[A,B,C,D,NPI,CPI]=Adjustingcode2(fdrpath1,sheetname,RepCondpath);
for i=1:length(R)
if NPI_updated(i) > 1
[A,B,C,D,NPI,CPI]=Adjustingcode2(fdrpath1,sheetname,RepCondpath);
end
if CPI_updated(i) > 1
[A,B,C,D,NPI,CPI]=Adjustingcode2(fdrpath1,sheetname,RepCondpath);
end
end
  8 Comments
Lewis Waswa
Lewis Waswa on 1 Sep 2023
I have added the rest of the code should any of you want to take run the same.
Voss
Voss on 1 Sep 2023
@Lewis Waswa: Thank you for the code. I've run Adjustingcode2 and Adjustingcode3, with my best guess of what the inputs should be, and both return NPI and CPI values that are all less than 1. See below:
[NewRC,NewAmpC,NewR,NewAmp,NPI,CPI,R] = Adjustingcode2('Inputs_JP.xlsx','JP_fdr','ACSRtechnicalData.xlsx');
Feeder under analysis: Excel_feeder This feeder is Voltage Constrained!! FeederMD = 6.183073e+01 kVA Feeder under analysis: Excel_feeder This feeder is Voltage Constrained!! FeederMD = 6.183073e+01 kVA
Elapsed time is 2.440178 seconds.
close all
all(NPI < 1)
ans = logical
1
all(CPI < 1)
ans = logical
1
[NewRC,NewAmpC,NewR,NewAmp,NPI,CPI,R] = Adjustingcode3('Inputs_JP.xlsx','JP_fdr','ACSRtechnicalData.xlsx');
Feeder under analysis: Excel_feeder This feeder is Voltage Constrained!! FeederMD = 6.183073e+01 kVA
close all
all(NPI < 1)
ans = logical
1
all(CPI < 1)
ans = logical
1
What do I need to do to get some CPI and/or NPI values >= 1? In other words, how do I reproduce the problem you asked about?

Sign in to comment.

Answers (2)

dpb
dpb on 30 Aug 2023
Several issues here...
function [A1,B1,C1,D1,NPI_new,CPI_new] =CSS_iterate(fdrpath1,sheetname,RepCondpath)
[A,B,C,D,NPI,CPI]=Adjustingcode2(fdrpath1,sheetname,RepCondpath);
for i=1:length(R)
if NPI_updated(i) > 1
[A,B,C,D,NPI,CPI]=Adjustingcode2(fdrpath1,sheetname,RepCondpath);
end
if CPI_updated(i) > 1
[A,B,C,D,NPI,CPI]=Adjustingcode2(fdrpath1,sheetname,RepCondpath);
end
end
[A,B,C,D,NPI,CPI]=Adjustingcode2(fdrpath1,sheetname,RepCondpath);
for i=1:length(R)
if NPI_updated(i) > 1
  1. R is undefined
  2. NPI/CPI_updated are never calculated; you return the (so it says) adjusted values in the NPI/CPI arrays, but then test a variable that never changes.
  3. if() on and array is true, IF AND ONLY IF all elements of the array are true so the above tests will always be called until all elements in the array <=1. Whether that would be true if were testing the NPI and CPI values instead would all depend upon what the adjusting code actually does which we are not privy to.
That's for starters, at least. Undoubtedly there will be more if/when get enough to be able to test...

Walter Roberson
Walter Roberson on 31 Aug 2023
Suppose you have the task of moving one brick at a time to the left until you reach the edge, and you start at brick #4. Then consider the following potential recursive solution:
function move_left_ver1(bricknum)
move_left_ver1(bricknum);
bricknum = bricknum - 1;
end
now we call move_left_ver1(4) and the first thing it does is call move_left_ver1(4) . And the first thing that does is call move_left_ver1(4) ... It cannot ever get a chance to subtract 1 from the brick number until all of the calls to move_left_ver1 are finished... but they never finish.
If you have a recursive program and the function calls itself with the exact same parameter values that were passed into it, the only way the program can stop running is if the program tests something external, such as a random number generator, or such as looking for the user to press a Cancel button.
Now let us consider
function move_left_ver2(bricknum)
bricknum = bricknum - 1;
move_left_ver2(bricknum);
end
We call move_left_ver2(4) and it subtracts 1 making bricknum into 3, and calls move_left_ver2(3) -- which is a different input parameter, so there is hope so far. move_left_ver2(3) will call move_left_ver2(2) which will call move_left_ver2(1) . Then move_left_ver2(1) will decrement bricknum to 0, and will call move_left_ver2(0) which will call move_left_ver2(-1) then -2 then ... and it will keep going until MATLAB decides you've probably made a mistake.
If you have a program that calls itself and you've made sure to call with different parameter values... you need some way of detecting that you have finished.
... and your test for being finished has to be before the recursive call. The chain of calls has to end somewhere!

Products


Release

R2022a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!