Unable to understand the recursion tree for the problem, printing all permutations of a given string - recursion

This is with respect to the problem, printing all permutations of a given string ABC. As far as I have understood, the program first prints ABC, then the string gets reset to ABC (which is the same as the first permutation of the string in this case) through backtracking, and then when i=1 and j=2, letters B and C are swapped, following which i gets incremented to 2 and is passed to the permute function where the second permutation ACB is printed on the screen. Following this, backtracking again takes place and we get back ABC.
I'm unable to understand how the next permutation BAC gets printed. For this the value of i would have to be reset to 0 (previously i=2 when we print out ACB) and the value of j should equal 1. (previously j=2 when the swapping of B and C takes place). How does i=0 and j=1, when there is no line of code in this program that does the same?
P.S: The code works fine, but I'm unable understand why it works the way it works. If anyone could trace the code step by step for each permutation it prints on the screen, that would be really helpful!
Here is the code:
void permute(String s, int i=0){
if(i==s.length()-1){
System.out.println(s);
return;
}
for(int j=i; j<s.length(); j++){
swap(s[i], s[j]);
permute(s, i+1);
swap(s[i], s[j]);
}
}

Related

Why is the FOR loop in my program producing empty matrices?

I am having a problem running a spiking-neuron simulator. I keep getting the error message, "operation +: Warning adding a matrix with the empty matrix will give an empty matrix result." Now I'm writing this program in "Scilab," but I'm hoping the problem I am having will be clear for the educated eye regardess. What I am doing is converting an existing MATLAB program to Scilab. The original MATLAB program and an explanation can be found here: https://www.izhikevich.org/publications/spikes.pdf
What happens in my Scilab version is that the first pass through the loop produces all the expected values. I Know this becuase I hit pause at the end of the first run, right before "end," and check all the values and matrix elements. However, if I run the program proper, which includes a loop of 20 iterations, I get the error message above, and all of the matrix values are empty! I cannot figure out what the problem is. I am fairly new to programming so the answer may be very simple as far as I know. Here is the Scilab version of the program:
Ne=8; Ni=2;
re=rand(Ne,1); ri=rand(Ni,1);
a=[0.02*ones(Ne,1); 0.02+0.08*ri];
b=[0.2*ones(Ne,1); 0.25-0.05*ri];
c=[-65+15*re.^2; -65*ones(Ni,1)];
d=[8-6*re.^2; 2*ones(Ni,1)];
S=[0.5*rand(Ne+Ni,Ne), -rand(Ne+Ni,Ni)];
v=60*rand(10,1)
v2=v
u=b.*v;
firings=[];
for t=1:20
I=[5*rand(Ne,1,"normal");2*rand(Ni,1,"normal")];
fired=find(v>=30);
j = length(fired);
h = t*ones(j,1);
k=[h,fired'];
firings=[firings;k];
v(fired)=c(fired);
u(fired)=u(fired)+d(fired);
I=I+sum(S(:,fired),"c");
v=v+0.5*(0.04*v.^2+5*v+140-u+I);
v=v+0.5*(0.04*v.^2+5*v+140-u+I);
u=u+a.*(b.*v-u);
end
plot(firings(:,1), firings(:,2),".");
I tried everything to no avail. The program should run through 20 iterations and produce a "raster plot" of dots representing the fired neurons at each of the 20 time steps.
You can add the following line
oldEmptyBehaviour("on")
at the beginning of your script in order to prevent the default Scilab rule (any algebraic operation with an empty matrix yields an empty matrix). However you will still have some warnings (despite the result will be OK). As a definitive fix I recommend testing the emptyness of fired in your code, like this:
Ne=8; Ni=2;
re=rand(Ne,1); ri=rand(Ni,1);
a=[0.02*ones(Ne,1); 0.02+0.08*ri];
b=[0.2*ones(Ne,1); 0.25-0.05*ri];
c=[-65+15*re.^2; -65*ones(Ni,1)];
d=[8-6*re.^2; 2*ones(Ni,1)];
S=[0.5*rand(Ne+Ni,Ne), -rand(Ne+Ni,Ni)];
v=60*rand(10,1)
v2=v
u=b.*v;
firings=[];
for t=1:20
I=[5*rand(Ne,1,"normal");2*rand(Ni,1,"normal")];
fired=find(v>=30);
if ~isempty(fired)
j = length(fired);
h = t*ones(j,1);
k=[h,fired'];
firings=[firings;k];
v(fired)=c(fired);
u(fired)=u(fired)+d(fired);
I=I+sum(S(:,fired),"c");
end
v=v+0.5*(0.04*v.^2+5*v+140-u+I);
v=v+0.5*(0.04*v.^2+5*v+140-u+I);
u=u+a.*(b.*v-u);
end
plot(firings(:,1), firings(:,2),".");
The [] + 1 is not really defined in a mathematical sense. The operation might fail or produce different results depending on the software you use. For example:
Scilab 5 [] + 1 produces 1
Scilab 6 [] + 1 produces [] and a warning
Julia 1.8 [] .+ 1 produces [] but [] + 1 an error.
Python+Numpy 1.23 np.zeros((0,0)) + 1 produces [].
I suggest checking with size() or a comparison to the empty matrix to avoid such strange behaviour.

Finding limits at infinity in R

I am doing an R code to evaluate limits.
I am not sure if my code even works I just run it and then it doesn't give anything and R stop debugging code / gets stuck, nothing works right after not even print statements. fn is supposed to be any function and tol is the error tolrence, I want to stop the program when the consective terms difference is less than 1e-6. I have to restart R and I always get the message "R session is currently busy" when I try to close R studio
lim<-function(funx,tol=1e-6){
n<-1
while(TRUE){
n<-n+1
term<-funx
next_term<-term+funx
if(abs(term-next_term)<tol){
break
}
}
return(term)
}
n<-1
fn<-(1/5)**n
lim(fn)
You made some mistakes in your program. For one, you always add the same number (funx) which will always be 0.20 and never smaller than the tolerance, so you get an endless loop.
If you want to call a function each time, you have to define this function and pass it to the lim() function. Otherwise, you just define fn as 0.20 and pass it as a double value to the function. It will never change.
If you want to find the limes of (1/5)^n, you can do it like that:
lim = function(f,x=1,tol=0.0001){
next.diff=tol
while(next.diff>=tol){
next.diff = abs(f(x)-f(x+1))
x = x + 1
}
return(list("Iterations"=x,"Limit"=f(x),"Next Value"=f(x+1)))
}
my.fun = function(x){(1/5)^x}
lim(my.fun,1,1e-6)
It wil lthen call the function for inceasing values of x and abort the loop as soon as the tolerance is reached. In this example:
> lim(my.fun,1,1e-6)
$Iterations
[1] 10
$Limit
[1] 1.024e-07
$`Next Value`
[1] 2.048e-08
So, at (1/5)^10 you already reach a value where the next iteration is closer than your tolerance. It's safe to say that it would converge to 0.
You can define any function of a value x and pass it to this lim function with a starting value for x and a tolerance level.
EDIT: For the limes of sqrt(x+1)-sqrt(x), you would just have to define a new function of x (or of n, if you wish) and pass it to lim():
> fun2 = function(x){sqrt(x+1)-sqrt(x)}
> lim(fun2,1,1e-6)
$Iterations
[1] 3969
$Limit
[1] 0.007936008
$`Next Value`
[1] 0.007935009
It's unclear as to what you really want to find out here, but as far as I understood, you want to see where the sequence (not a function) (and of the type a^n) converges. Well, if that is the case, then you need to change your code to something like this:
lim<-function(a,tol=1e-6)
{
n<-1
repeat
{
term<-a^n;next_term<-a^(n+1)
if(abs(term-next_term)<tol) break
n<-n+1
}
return(term)
}
Ok so here's what I did:
I assumed that the sequence you input is of the form a^n where a is a constant term, and n increase on the set of natural numbers
I defined the value of n initially inside the loop (why? cause I want to iterate over all the possible values of n, one-by-one)
Then I defined the first term of the sequence (named as term). As assumed, it's a^n initially. So the next term (a.k.a. next_term in my code) should be a^(n+1).
Now take their absolute difference. If it satisfies the condition, break out from the loop. Else, increase the value of n by 1 and let the loop run once again.
Then finally, return the value of the term. That's all...
I hope you will now be able to understand where you went wrong. Your approach was similar, but the code was of something else.
Remember, in this code, you don't need to enter the value of n separately while calling the function.
Here's what it returned:
> lim(1/5)
[1] 5.12e-07
> fn<-1/12
> lim(fn)
[1] 3.34898e-07

Count the number of statements per line in C/C++

Given a C program (could be a C++, although for now, i'd stick to C), I want to count the number of statements for every line of code (excluding comments etc of course)
I have been writing a parser to do that - but clearly i keep encountering code that kinda fails.
so if a code line has "i= 0; i++; i--;" on a single line, i want my parser to return 3 for this line. If i have "if (x) { x++}; else x--;" on a single line, then it should return 3 (if, x++, x--). Are there tools that already do this (does pycparser provide an option to return the number of statements in a given line?)

Recursion with code after the recursive call

I am trying to understand how recursion works and there is just one more thing that I do not quite understand: how a recursive function works when there is code after the recursive call within the recursive function itself. Please see below at the example pseudocode to help see what I mean. My exact question is in what order (meaning when) the code after that recursive call will be executed. Will the machine note the recursive call, execute the remaining bit of code after the call (print "done"), then go back and actually execute the entire recursive call, or will the machine execute the recursive call as soon as it gets to that line and only execute that last bit of code (print "done") after that recursion bottoms out? When and how many times will "done" be printed?
void recurse()
{
print "hello world";
for i = 0 up to 2
recurse();
print "done";
}
The recursive call runs BEFORE any code below it. Once it returns, it will go back and finish the rest of the code. So what happens is
"hello world"
i = 0
"hello world"
i = 0
"hello world"
...
forever. Because you don't pass the value of i to the next recursive function, your code will run forever, restarting each time with i=0.
Let's assume though that you did pass i to the recursive function properly:
void recurse(i) {
// is i still < 2?
if (i < 2) {
print "hello world";
recurse(i+1);
print "done";
}
recurse(0);
In this case, you would get:
i = 0
"hello world"
i = 1
"hello world"
i = 2
"done"
"done"
A good way to visualize recursion is using the depth/height of the stack. As you may know, whenever a new function is called, it's pushed onto the stack like a pancake, increasing the depth/height by 1. If you code it up and print your "start" and "end" notes with an indentation to visualize the depth, it should be easy to see what is executed when. In case it isn't clear, time is on the Y-axis (things printed above have executed before things below) and recursion depth is on the X-axis.
Here's the code in Python:
def recurse(depth=0):
if depth < 4:
print(" " * depth + f"starting at depth {depth}")
for _ in range(2):
recurse(depth + 1)
print(" " * depth + f"ending at depth {depth}")
recurse()
Output:
starting at depth 0
starting at depth 1
starting at depth 2
starting at depth 3
ending at depth 3
starting at depth 3
ending at depth 3
ending at depth 2
starting at depth 2
starting at depth 3
ending at depth 3
starting at depth 3
ending at depth 3
ending at depth 2
ending at depth 1
starting at depth 1
starting at depth 2
starting at depth 3
ending at depth 3
starting at depth 3
ending at depth 3
ending at depth 2
starting at depth 2
starting at depth 3
ending at depth 3
starting at depth 3
ending at depth 3
ending at depth 2
ending at depth 1
ending at depth 0
As can be seen, there are two identical recursive calls that are spawned in the loop. The first trip through the loop completes its entire recursive execution before the second one begins. After both recursive calls complete, then the entire call ends.
Also note that the depth represents a base case or terminal/leaf node that has no children. Your original algorithm will recurse infinitely and blow the stack.

OpenCL result changes depending on result of printf? What?

OpenCL kernel crunches some numbers. This particular kernel then searches an array of 8 bit char4 vectors for a matching string of numbers. For example, array holds 3 67 8 2 56 1 3 7 8 2 0 2 - the kernel loops over that (actual string is 1024 digits long) and searches for 1 3 7 8 2 and "returns" data letting the host program know it found a match.
In an combo learning exercise/programming experiment I wanted to see if I could loop over an array and search for a range of values, where the array is not just char values, but char4 vectors, WITHOUT using a single if statement in the kernel. Two reasons:
1: After half an hour of getting compile errors I realized that you cannot do:
if(charvector[3] == searchvector[0])
Because some may match and some may not. And 2:
I'm new to OpenCL and I've read a lot about how branches can hurt a kernel's speed, and if I understand the internals of kernels correctly, some math may actually be faster than if statements. Is that the case?
Anyway... first, the kernel in question:
void search(__global uchar4 *rollsrc, __global uchar *srch, char srchlen)
{
size_t gx = get_global_id(0);
size_t wx = get_local_id(0);
__private uint base = 0;
__local uchar4 queue[8092];
__private uint chunk = 8092 / get_local_size(0);
__private uint ctr, start, overlap = srchlen-1;
__private int4 srchpos = 0, srchtest = 0;
uchar4 searchfor;
event_t e;
start = max((int)((get_group_id(0)*32768) - overlap), 0);
barrier(CLK_LOCAL_MEM_FENCE);
e = async_work_group_copy(queue, rollsrc+start, 8092, 0);
wait_group_events(1, &e);
for(ctr = 0; ctr < chunk+overlap; ctr++) {
base = min((uint)((get_group_id(0) * chunk) + ctr), (uint)((N*32768)-1));
searchfor.x = srch[max(srchpos.x, 0)];
searchfor.y = srch[max(srchpos.y, 0)];
searchfor.z = srch[max(srchpos.z, 0)];
searchfor.w = srch[max(srchpos.w, 0)];
srchpos += max((convert_int4(abs_diff(queue[base], searchfor))*-100), -100) | 1;
srchpos = max(srchpos, 0);
srchtest = clamp(srchpos-(srchlen-1), 0, 1) << 31;
srch[0] |= (any(srchtest) * 255);
// if(get_group_id(0) == 0 && get_local_id(0) == 0)
// printf("%u: %v4u %v4u\n", ctr, srchpos, srchtest);
}
barrier(CLK_LOCAL_MEM_FENCE);
}
There's extra unneeded code in there, this was a copy from a previous kernel, and I havent cleaned up the extra junk yet. That being said.. in short and in english, how the math based if statement works:
Since I need to search for a range, and I'm searching a vector, I first set a char4 vector (searchfor) to have elements xyzw individually set to the number I am searching for. It's done individually because each of xyz and w hold a different stream, and the search counter - how many matches in a row we've had - will be different for each of the members of the vector. I'm sure there's a better way to do it than what I did. Suggestions?
So then, an int4 vector, searchpos, which holds the current position in the search array for each of the 4 vector positions, gets this added to it:
max((convert_int4(abs_diff(queue[base], searchfor))*-100), -100) | 1;
What this does: Take the ABS difference between the current location in the target queue (queue) and the searchfor vector set in the previous 4 lines. A vector is returned where each member will have either a positive number (not a match) or zero (a match - no difference).
It's converted to int4 (as uchar cannot be negative) then multipled by -100, then run through max(x,-100). Now the vector is either -100, or 0. We OR it with 1 and now it's -99 or 1.
End result: searchpos either increments by 1 (a match), or is reduced by 99, resetting any previous partial match increments. (Searches can be up to 96 characters long - there exists a chance to match 91, then miss, so it has to be able to wipe that all out). It is then max'ed with 0 so any negative result is clamped to zero. Again - open to suggestions to make that more efficient. I realized as I was writing this I could probably use addition with saturation to remove some of the max statements.
The last part takes the current srchpos, which now equals the number of consecutive matches, subtracts 1 less than the length of the search string, then clamps it to 0-1, thus ending up with either a 1 - a full match, or 0. We bit shift this << 31. Result is 0, or 0x8000000. Put this into srchtest.
Lastly, we bitwise OR the first character of the search string with the result of any(srchtest) * 255 - it's one of the few ways (I'm aware of) to test something across a vector and return a single integer from it. (any() returns 1 if any member of the vector has it's MSB set - which we set in the line above)
End result? srch[0] is unchanged, or, in the case of a match, it's set to 0xff. When the kernel returns, the host can read back srch from the buffer. If the first character is 0xff, we found a match.
It probably has too many steps and can be cleaned up. It also may be less efficient than just doing 4 if checks per loop. Not sure.
But, after this massive post, the thing that has me pulling my hair out:
When I UNCOMMENT the two lines at the end that prints debug information, the script works. This is the end of the output on my terminal window as I run it:
36: 0,0,0,0 0,0,0,0
37: 0,0,0,0 0,0,0,0
38: 0,0,0,0 0,0,0,0
39: 0,0,0,0 0,0,0,0
Search = 613.384 ms
Positive
Done read loop: -1 27 41
Positive means the string was found. The -1 27 41 is the first 3 characters of the search string, the first being set to -1 (signed char on the host side).
Here's what happens when I comment out the printf debugging info:
Search = 0.150 ms
Negative
Done read loop: 55 27 41
IT DOES NOT FIND IT. What?! How is that possible? Of course, I notice that the script execution time jumps from .15ms to 600+ms because of the printf, so I think, maybe it's somehow returning and reading the data BEFORE the script ends, and the extra delay from the printf gives it a pause. So I add a barrier(CLK_LOCAL_MEM_FENCE); to the end, thinking that will make sure all threads are done before returning. Nope. No effect. I then add in a 2 second sleep on the host side, after running the kernel, after running clFinish, and before running clReadBuffer.
NOPE! Still Negative. But I put the printf back in - and it works. How is that possible? Why? Does anyone have any idea? This is the first time I've had a programming bug that baffled me to the point of pulling hair out, because it makes absolutely zero sense. The work items are not clashing, they each read their own block, and even have an overlap in case the search string is split across two work item blocks.
Please - save my hair - how can a printf of irrelevant data cause this to work and removing it causes it to not?
Oh - one last fun thing: If I remove the parameters from the printf - just have it print text like "grr please work" - the kernel returns a negative, AND, nothing prints out. The printf is ignored.
What the heck is going on? Thanks for reading, I know this was absurdly long.
For anyone referencing this question in the future, the issue was caused by my arrays being read out of bounds. When that happens, all heck breaks loose and all results are unpredictable.
Once I fixed the work and group size and made sure I was not exceeding the memory bounds, it worked as expected.

Resources