How do I trace recursive function - c++

So in one of my class I am learning recursion and there is a question which I tried to trace through but couldn't get the right answer.
I keep geting 11 but the right answer is 6. Can someone help me get a better understanding and hopefully explain how you would trace through the code please. Thank you.
The way I tracing it right now:
int f(int x, int y) {
if (x <= 0) {
return y;
}
return f(x - 1, y + 1) - f(x / 2, y * 2);
}
What is f(4, -1)?
f(4,-1)
return f(3,0) - f(2,-2)
return f(2,1) - f(1,-4)
return f(1,2) - f(0,-8)
return f(0,3) - (-8)
return 3 + 8 = 11.

You are not taking into account that most of the calls to f() are then making 2 internal calls to f(). So the real trace would break down more like the following. The real answer is 2, not 6 like your professor told you:
f(4,-1) = f(3,0) - f(2,-2)
(
f(3,0) = f(2,1) - f(1,0)
(
f(2,1) = f(1,2) - f(1,2)
(
f(1,2) = f(0,3) - f(0,4)
(
f(0,3) = 3
)
(
f(0,4) = 4
)
= (3) - (4) = -1
)
(
f(1,2) = f(0,3) - f(0,4)
(
f(0,3) = 3
)
(
f(0,4) = 4
)
= (3) - (4) = -1
)
= (-1) - (-1) = 0
)
(
f(1,0) = f(0,1) - f(0,0)
(
f(0,1) = 1
)
(
f(0,0) = 0
)
= (1) - (0) = 1
)
= (0) - (1) = -1
)
(
f(2,-2) = f(1,-1) - f(1,-4)
(
f(1,-1) = f(0,0) - f(0,-2)
(
f(0,0) = 0
)
(
f(0,-2) = -2
)
= (0) - (-2) = 2
)
(
f(1,-4) = f(0,-3) - f(0,-8)
(
f(0,-3) = -3
)
(
f(0,-8) = -8
)
= (-3) - (-8) = 5
)
= (2) - (5) = -3
)
= (-1) - (-3) = 2
final answer: 2
Live Demo

Here is ASCII art with control flow for recursive call,
f(4,-1)-------->+
. //f(4 - 1, -1 + 1)
. f(3,0)------->+
. . |
. . //f(3-1,0+1)
. . f(2,1)----------->+
. . . |
. . . // f(2-1,1+1)
. . . f(1,2)--------->+
. . . . |
. . . . //f(1-1,2+1)
. . . . f(0,3)--------->+
. . . . . //as (x == 0) return 3
. . . . . |
. . . . |<----(3)---+
. . . . |
. . . . //f(1/2,2*2)
. . . . f(0,4)--------->+
. . . . . //as (x == 0) return 4
. . . . . |
. . . . +<----(4)---+
. . . . |
. . . . //f(1-1,2+1) - f(1/2,2*2) = 3 - 4 = -1
. . . +<---(-1)---+
. . . |
. . . // f(2/2,1*2)
. . . f(1,2)--------->+
. . . . |
. . . . //f(1-1,2+1)
. . . . f(0,3)--------->+
. . . . . //as (x == 0) return 3
. . . . . |
. . . . +<----(3)---+
. . . . |
. . . . //f(1/2,2*2)
. . . . f(0,4)--------->+
. . . . . //as (x == 0) return 4
. . . . . |
. . . . +<----(4)---+
. . . . |
. . . . //f(1-1,2+1) - f(1/2,2*2) = 3 - 4 = -1
. . . +<---(-1)---+
. . +<----(0)-------+
. . |
. . //f(3/2,0*2)
. . f(1,0)----------->+
. . . |
. . . //f(1-1,0+1)
. . . f(0,1)--------->+
. . . . //as (x == 0) return 1
. . . . |
. . . +<----(1)---+
. . . |
. . . //f(1/2,0*2)
. . . f(0,0)--------->+
. . . . //as (x == 0) return 0
. . . . |
. . . +<----(0)---+
. . . |
. . . //f(0,1)-f(0,0) = 1- 0 = 0
. . +<-----(1)------+
. . |
. . // f(3-1,0+1) - f(3/2,0*) = 0 - 1 = -1
. +<----(-1)--+
. |
. //f(4/2,-1*2)
. f(2,-2)------->+
. . |
. . //f(2-1,-2+1)
. . f(1,-1)---------->+
. . . |
. . . //f(2-1,-2+1)
. . . f(0,0)--------->+
. . . . //as (x == 0) return 0
. . . . |
. . . +<----(0)---+
. . . |
. . . //f(1/2,-1*2)
. . . f(0,-2)-------->+
. . . . //as (x == 0) return -2
. . . . |
. . . +<---(-2)---+
. . . |
. . . //f(0,0)-f(0,-2) = 0 - (-2) = 2
. . +<----(2)-------+
. . |
. . //f(2/2,-2*2)
. . f(1,-4)---------->+
. . . |
. . . f(0,-3)-------->+
. . . . //as (x == 0) return -3
. . . . |
. . . +<---(-3)---+
. . . |
. . . f(0,-8)-------->+
. . . . //as (x == 0) return -8
. . . . |
. . . +<---(-8)---+
. . . |
. . . //f(0,-3) -f(0,-8) = -3 -(-8) = 5
. . +<-----(5)------+
. . |
. . //f(1,-1)-f(1,-4) = 2 - 5 = -3
. +<----(-3)--+
. |
. //f(4 - 1, -1 + 1) - f(4/2,-1*2) = -1 - (-3) = 2
<----(2)----+
How to understand,
Each column represents a function call which makes 2 subsequent recursive calls.
<--(x)--- represents return value x
When function f(x,y) is called, recursive call for f(x-1,y+1) is called until x is zero and then f(x/2,y*2) is called recursively.
Consider below case with f(1,2) call makes two subsequent recursive call to f(0,3) and f(0,4) and return value from both is computed back as return value of f(1,2)
f(1,2)--------->+
. |
. //f(1-1,2+1)
. f(0,3)--------->+
. . //as (x == 0) return 3
. . |
. |<----(3)---+
. |
. //f(1/2,2*2)
. f(0,4)--------->+
. . //as (x == 0) return 3
. . |
. +<----(4)---+
. |
. //f(1-1,2+1) - f(1/2,2*2) = 3 - 4 = -1
+<---(-1)---+
Let me try to put it in different way,

If you want, you can manually print out the traces. Probably not as good as a debugger in most cases, but it can occasionally come in handy. https://godbolt.org/z/WpSYNj
#include <iostream>
int g_tabs = 0;
struct trace
{
trace(int x, int y)
{
for(int i = 0; i < g_tabs; ++i)
std::cout << " ";
std::cout << "f(" << x << ", " << y << ") {\n";
++g_tabs;
}
~trace()
{
--g_tabs;
for(int i = 0; i < g_tabs; ++i)
std::cout << " ";
std::cout << "}\n";
}
};
void print(int res)
{
for(int i = 0; i < g_tabs; ++i)
std::cout << " ";
std::cout << "result[ " << res << " ]\n";
}
void print(int l, int r, int res)
{
for(int i = 0; i < g_tabs; ++i)
std::cout << " ";
std::cout << "result[ " << res << " ] = " << l << " - " << r << '\n';
}
int f(int x, int y)
{
trace t(x, y);
if (x <= 0) {
print(y);
return y;
}
int left = f(x - 1, y + 1);
int right = f(x / 2, y * 2);
int result = left - right;
print(left, right, result);
return result;
}
int main()
{
f(5, 3);
return 0;
}

Related

armadillo: Get nonzero locations of sparse row vector from sparse matrix

I am using armadillo and R through RcppArmadillo.
I have a sparse matrix and a row number as input. I would like to search the corresponding row of the matrix and return the location of the nonzeros.
So far my function looks like
// [[Rcpp::export]]
arma::uvec findAdjacentStates(arma::sp_mat adjacency, int row) {
arma::uvec out(adjacency.n_cols);
arma::SpSubview<double>::const_iterator start = adjacency.row(row).begin();
arma::SpSubview<double>::const_iterator end = adjacency.row(row).end();
for(arma::SpSubview<double>::const_iterator it = start; it != end; ++it)
{
Rcout << "location: " << it.row() << "," << it.col() << " ";
Rcout << "value: " << (*it) << std::endl;
}
return out;
}
which is based on a previous SO answer.
The function crashes R.
require(Matrix)
x = rsparsematrix(10, 10, .2)
x = x > 1
x = as(x, "dgCMatrix")
findAdjacentStates(x, 1)
One thing that is not clear to me is how to iterate on a row vector specifically; the previous SO answer was for iterating on a sparse matrix.
Update: according to valgrind the problem is in operator++ (SpSubview_iterators_meat.hpp:319), so it seems this is not the correct way to iterate on a sparse row vector
The way to iterate on a sparse matrix row is with a sp_mat::row_iterator. Unfortunately, there's no way to know ahead of time what size your output vector would be and uvec objects don't have a push_back like regular vectors do. Here would be my suggestion:
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
using namespace Rcpp;
using namespace arma;
// [[Rcpp::export]]
IntegerVector findAdjacentStates(sp_mat adjacency, int row) {
IntegerVector out;
sp_mat::const_row_iterator start = adjacency.begin_row(row);
sp_mat::const_row_iterator end = adjacency.end_row(row);
for ( sp_mat::const_row_iterator i = start; i != end; ++i )
{
out.push_back(i.col());
}
return out;
}
Which we can test out easily enough:
# We need Rcpp and Matrix:
library(Rcpp)
library(Matrix)
# This is the C++ script I wrote:
sourceCpp('SOans.cpp')
# Make example data (setting seed for reproducibility):
set.seed(123)
x = rsparsematrix(10, 10, .2)
# And test the function:
findAdjacentStates(x, 1)
[1] 4
x
10 x 10 sparse Matrix of class "dgCMatrix"
[1,] . . 0.84 . 0.40 0.7 . . . -0.56
[2,] . . . . -0.47 . . . . .
[3,] . . . . . . . . -2.00 .
[4,] 0.15 . . . . . . . . -0.73
[5,] 1.80 . . . . . . . . .
[6,] . . . . . . . . 0.11 .
[7,] . . -1.10 . . . . -1.70 -1.10 .
[8,] . . . . . . . 1.30 . -0.22
[9,] -0.63 . 1.20 . . . . 0.36 . .
[10,] . . . . 0.50 -1.0 . . . .
So, we can see this works; row 1 (in C++ terms; row 2 in R terms) has only one non-zero element, which is in column 4 (in C++ terms; column 5 in R terms). This should work if you're wanting to return the output to R. If you're wanting to use the output in another C++ function, depending on what you're doing you may prefer to have a uvec rather than an IntegerVector, but you can just convert the IntegerVector to a uvec (probably not the most efficient solution, but the best I thought of right now):
// [[Rcpp::export]]
uvec findAdjacentStates(sp_mat adjacency, int row) {
IntegerVector tmp;
sp_mat::const_row_iterator start = adjacency.begin_row(row);
sp_mat::const_row_iterator end = adjacency.end_row(row);
for ( sp_mat::const_row_iterator i = start; i != end; ++i )
{
tmp.push_back(i.col());
}
uvec out = as<uvec>(tmp);
return out;
}

How can I find consecutively "occupied" elements in a C++ array?

I'm creating a command line game that includes a 10 x 10 char array, represented like this:
0 1 2 3 4 5 6 7 8 9
0 . . . . . . . . . .
1 . . . . . . . . . .
2 . . . . . . . . . .
3 . . . . . . . b . .
4 . . A B C . 1 2 3 .
5 . . . . . . . . . .
6 . . . . . . . . . .
7 . . . . . C c 3 . .
8 . . . . . . . . . .
9 . . . . . . . . . .
Each . represents an unoccupied spot on the board and the letters and numbers are pieces that have already been played. The numbers on the upper edge and left edge are just for reference.
In order to calculate points and ensure that pieces are played in the correct places, I'd like to create "sub-array" of consecutive pieces adjacent to the piece that has just been played. From the example above, if B had just been played, then that char array would contain A, B, and C.
I'm having a hard time finding the "starting" (left-most) and "ending" (right-most) pieces of this consecutive sub-array. Once I have those this is easy to solve. Obviously I could start at one end of the board and just add to an array any piece that's not ., but then I'd end up with all the pieces in that row, not just the ones adjacent to the piece that has just been played.
I've tried the following, but it still prints the wrong output (off by one on both sides):
void Board::createHorizontalRun(int row, int column) {
int i = column;
int j = column;
while (array[row][i] != '.' && i >= 0 && i <= 9) {
i--;
}
while (array[row][j] != '.' && j >= 0 && j <= 9) {
j++;
}
cout << "run begins at " << i << endl;
cout << "run ends at " << j << endl;
}
How can I find the starting and ending locations of the consecutive pieces adjacent to the piece that has just been played?
Here's what I came up with after following Sam's advice:
vector<char> Board::getHorizontalRun(int row, int column) {
int runStart = column;
int runEnd = column;
vector<char> horizontalRun;
// find starting position of run
while (true) {
if (isInBounds(row, runStart - 1)) {
if (array[row][runStart - 1] == '.') {
break;
} else {
runStart--;
}
} else {
break;
}
}
// find ending position of array
while (true) {
if (isInBounds(row, runEnd + 1)) {
if (array[row][runEnd + 1] == '.') {
break;
} else {
runEnd++;
}
} else {
break;
}
}
// Use start and end positions to populate vector
for (int i = runStart; i <= runEnd; i++) {
horizontalRun.push_back(array[row][i]);
}
return horizontalRun;
}

Array reference in Stata?

I need a Stata code similar to this SAS code:
i=1;
do while (i <= 6);
A=B(C(i));
i=i+1;
end;
Both B and C are arrays as
B_1, B_2, B_3, B_4, B_5 and B_6
C_1, C_2, C_3, C_4, C_5 and C_6
For example, if i = 1, then C(i) = C_1.
For row 3, if C_1 = 5, then I want to set A to B_5.
my problem is with accessing the array entry B(C(i)). How can I write this access in Stata?
There isn't a one-to-one equivalent. See
FAQ . . . . . . . . . . . . . . . . Implementing SAS-like ARRAYs in Stata
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . W. Gould
2/03 How do I implement SAS-like ARRAYs in Stata?
Here is a link.
This is a little clumsy, but (insofar as I understand the question) it does what you are asking for:
clear all
forvalues i = 1/6 {
scalar c_`i' = 7-`i'
}
forvalues i = 1/6 {
scalar b_`i' = ceil(100/`i')
}
// test method
forvalues i = 1/6 {
scalar a = b_`=c_`i''
di a
}
scalar list
Note that as you've written the question, a is overwritten each time, so presumably there are commands following "a = b(c(i))". The Stata syntax '=...' (with a proper opening single quote) evaluates the scalar c_'i' and inserts the resulting value in the name for b_?, which a is then set equal to.

Set Pandas Data Frame elements to 0 if corresponding element is False

I have two dataframes:
df0:
A B C
x y z
m n o
h i j
df1:
False False False
False True False
False False False
I want to get a "." only when the corresponding element in df1 is True:
df0:
A B C
. . .
. n .
. . .
You could use pandas.where:
In [139]: df0 = pd.DataFrame([list('xyz'),list('mno'),list('hij')], columns=list('ABC'))
In [143]: df1 = pd.DataFrame([(False,False,False),(False,True,False),(False,False,False)])
In [153]: df0.where(df1.values, other='.')
Out[153]:
A B C
0 . . .
1 . n .
2 . . .
[3 rows x 3 columns]

Can I "force" Cachegrind into analyzing an operation (or line)?

I am benchmarking the cache behaviour of two search algorithms that operate on a sorted range of items with Cachegrind. I have n items in a vector, and another vector that holds all valid indices. I use std::random_shuffle on the second vector, and do then perform n successful lookups on the items in the first vector. The function I am benchmarking looks roughly as follows:
template <typename Iterator>
void lookup_in_random_order(Iterator begin, Iterator end)
{
const std::size_t N = std::distance(begin, end);
std::vector<std::size_t> idx(N);
std::iota(idx.begin(), idx.end(), 0);
std::srand(std::time(0));
std::random_shuffle(idx.begin(), idx.end());
// Warm the cache -- I don't care about measuring this loop.
for(std::size_t i = 0; i < N; ++i)
my_search(begin, end, idx[i]);
std::random_shuffle(idx.begin(), idx.end());
// This one I would care about!
for(std::size_t i = 0; i < N; ++i)
{
int s = idx[i];
// Especially this line, of course.
my_search(begin, end, s);
}
}
I compile my code with g++ (with -g and -O2). I run Cachegrind and then cg_annotate. I get something like the following:
Ir I1mr ILmr Dr D1mr DLmr Dw D1mw DLmw
. . . . . . . . . template <typename Iterator>
17 2 2 0 0 0 6 0 0 void lookup_in_random_order(Iterator begin, Iterator end)
. . . . . . . . . {
. . . . . . . . . const std::size_t N = std::distance(begin, end);
. . . . . . . . . std::vector<std::size_t> idx(N);
. . . . . . . . . std::iota(idx.begin(), idx.end(), 0);
. . . . . . . . .
4 0 0 0 0 0 2 1 1 std::srand(std::time(0));
. . . . . . . . . std::random_shuffle(idx.begin(), idx.end());
. . . . . . . . .
3,145,729 0 0 0 0 0 0 0 0 for(std::size_t i = 0; i < N; ++i)
. . . . . . . . . my_search(begin, end, idx[i]);
. . . . . . . . .
. . . . . . . . . std::random_shuffle(idx.begin(), idx.end());
. . . . . . . . .
3,145,729 1 1 0 0 0 0 0 0 for(std::size_t i = 0; i < N; ++i)
. . . . . . . . . {
1,048,575 0 0 1,048,575 132,865 131,065 0 0 0 int s = idx[i];
. . . . . . . . . my_search(begin, end, s);
. . . . . . . . . }
7 0 0 6 1 1 0 0 0 }
For some reason, some lines (especially the most interesting one!) consist of dots. Now, the Cachegrind manual says "Events not applicable for a line are represented by a dot. This is useful for distinguishing between an event which cannot happen, and one which can but did not."
How should this be interpreted? My first idea was that maybe the compiler optimizes my searches away. I thought this cannot be, because the program did spend quite a bit of time running. Still, I tried compiling without the -O2 flag and it seemed to work in a sense that now every line with a call to my_search recorded some numbers (no dots anymore!). However, this doesn't seem like the right way to go for obvious reasons.
In general, is there a way I can tell Cachegrind that "look at this line especially, I am very interested how many cache misses it causes"?
My guess is that with O2 it allows the compiler to perform automatic inlining of the functions where you see the dots. Cachegrind will not see the inlined function calls as the calls have dissappeared. Try "-fno-inline" (Compiler options)
Of course you will probably have different cache performance numbers with and without inlining.