For-loop in Qlang?

There seems to be many ways to create for-loops in Qlang. Which options do I have and what is the difference?

Hi,
welcome to the community.
There are several ways that are equal in terms of performance. I will list them in a code example below. (I guess the “old style” is obsolete and compiles for backwards compability reasons. /Robert

//create a random matrix and flip it a 1000 times.

out matrix(number) old_style()
{
	matrix(number) x = rng_matrix(100,100);
	for (i:0,1000){
		x = m_flip_vt(x);
	}
	return x;
}

out matrix(number) cpp_style()
{
	matrix(number) x = rng_matrix(100,100);
	for (integer i=0;i<1000;i++){
		x = m_flip_vt(x);
	}
	return x;
}

out matrix(number) range_style()
{
	matrix(number) x = rng_matrix(100,100);
	vector(integer) v =  vector(i:1000;i);

	for (i:v){
		x = m_flip_vt(x);
	}
	return x;
}
1 Like

To add to this, the range style for loop is more capable than immediately obvious. You can loop through several vectors together (provided they have the same size), and you can change the values in the vectors by declaring the loop-variable out.

vector(number) range_loop()
{
	vector(number) v_one = vector(i:100; (i%15)/3);
	vector(number) v_two = vector(i:100; (i%22)/4);
	vector(number) v_result[100];

	for (out r : v_result, x : v_one, y : v_two) {
		r = abs(x-y);
	}

	return v_result;
}
2 Likes

Hi Joel!
You are absolutely correct. There is also the added benefit that “range-loop” is more efficient. This due to the fact that range checking is only done once in for(…) statement, and will throw already at this point if there is a mismatch. A normal for loop that contains vectors will have to range check in each iteration.

The cost of range checking shows only for very large problems of course.

There is a subtle thing about the old-style for loop. It automatically steps downward if start is greater than end. This code

for(i: 0, v_size(v)-1) {
     do_something(v[i]);
}

which, when given a zero length vector will execute the body of the loop.
The easiest way to fix this is adding an explicit step.

for(i: 0, v_size(v)-1, 1) {
     do_something(v[i]);
}

1 Like

Update! Since Quantlab version 4114, the range style for-loop also provides a way to get a named index variable in the loop. Can be very useful for debugging or printing something within the loop. It is created by adding a named index variable after a semi-colon at the end. See below, adding to the previous example.

out vector(number) range_loop()
{
	logical debug = true;
	vector(number) v_one = vector(i:100; (i%15)/3);
	vector(number) v_two = vector(i:100; (i%22)/4);
	vector(number) v_result[100];

	for (out r : v_result, x : v_one, y : v_two; j) {
		r = abs(x-y);
		if(debug)
			log_message(LOG_INFO, strcat('Debug problem on iteration # ', string(j)));
	}

	return v_result;
}