equality testing in for loops - c

I'm currently writing a program to calculate arctangent using a Taylor Series sum. The centre part of the code is the following:
for(int i=0;i<n;i++)
{
firstval=sum; //sum=0
sum=sum+sumterm(x,i); //calculate the sum
if(fabs(sum-firstval)<delta) //delta=10e-6
{
s=i;
}
else s=0;
}
How I think this code is working: 'sum' is initialised to 0, meaning that 'firstval' is as well. The program then calculates the Taylor series value for a particular value of i, and adds it on to the sum. Then, as 'sum' and 'firstval' are different, the magnitude of their difference can be calculated - as the loop proceeds, firstval is the previous value of the sum, and then in the loop, sum becomes its next term. Then when the difference between them is sufficiently small, and the condition is matched, the value of i for which that has happened is saved to an integer s, which is otherwise 0.
However, the program currently only produces 0, or says that the sum has only converged at n-1. I've spent quite a while playing around with different configurations of the code and can't work out why it's doing what it is. I'm still a newbie to this programming thing, so any help is welcome. Sorry if this post is unclear, I know that I haven't included the rest of the program, but I've had a quite long and tiring day. Thanks :)

You may want to use a while loop instead. The condition to exit the while loop could be:
while (fabs(sum-firstval)>delta)
Otherwise, other suggestions (using a break after variable s has been assigned value of i) work too.

Related

how to simulate loop in turbo prolog

I want to compute the summation of odd numbers in a given range like 1 to 9 is the given input. and my program will show the summation of all odd numbers between 1 to 9. Though the task is so simple theoriticaly, but as a starter of turbo prolog, I can't handle the loop to compute the summation. Any help would be appreciating..
Advance thanks.
I'm not going to write the full solution for you, but can give an idea how to "loop" through a summation in a general way. Looping in Prolog is often done through recursion. The recursion gets around the fact that Prolog will not let you reinstantiate a variable within the same predicate clause once it's instantiated (unless you backtrack). The following is ISO Prolog syntax.
sum_values(First, Last, Sum) :-
sum_values(First, Last, 0, Sum).
sum_values(First, Last, Sum, Sum) :-
First > Last.
sum_values(First, Last, Acc, Sum) :-
First =< Last,
NewAcc is Acc + First,
NewFirst is First + 1,
sum_values(NewFirst, NewAcc, Sum).
The first clause sets up an accumulator starting at the value 0.
The second clause handles the normal recursive case where the first value does not exceed the last. The first value is added to the accumulator to create an updated accumulator, and the "first" value is incremented to create a new first value. The recursive call to sum_values computes the rest of the sum with the new accumulator.
The last (third) clause unifies the final sum with the accumulator when the first value finally exceeds the last.
Note that I could have implemented this without introducing the accumulator, but then I wouldn't have the tail recursion which can be optimized (if desired) by the Prolog system. The non-accumulator version looks like this:
sum_values(First, Last, 0) :- First > Last.
sum_values(First, Last, Sum) :-
First =< Last,
NewFirst is First + 1,
sum_values(NewFirst, Last, PartialSum),
Sum is PartialSum + First.
This is a little shorter, but there's no tail recursion that can be refactored.
Modifications you would need to make for your problem (these are ones I'm aware of, as I'm only a little familiar with some of TP's syntax):
Replace is/2 with =/2 (I think TP uses =/2 for expression evaluation)
You might have to replace =< with <= (I don't recall which one TP likes)
Check that First is odd. If it's not, you need to skip adding it to the accumulator.
You could also do an initial check for odd First and if it's not odd, increment it to form a new First, then proceed doing a summation incrementing by 2 through the recursion instead of by 1.

End condition of an IF loop that depends on a 3D array

I'm writing a program which will move a particle about a cube, either left,right,up,down, back or forward depending on the value randomly generator by the program. The particle is able to move with cube of dimensions LxLxL. I wish the program to stop when the particle has been to all possible sites and the number of jumps taken output.
Currently I am doing this using an array[i][j][k] and when the particle has been to a position, changing the value of the array at that corresponding point to 0. However, in my IF loop I have to type out every possible combination of i,j and k in order to say if they are all equal to 0 the program should end. Would there be a better way to do this?
Thanks,
Beth
Yes. I'm assuming the if in question is the one contained within the triple nested loop who's body sets finish=1;. The better way of doing this is to set a your flag before the loop, beginning with a true value then setting it to false and breaking if you encounter a value other then zero. Your if statement becomes much simpler, like this;
int finish =1; // start with a true value
//loops are untouched so still got the for i and for j above this
for(k = 0; k < 15; k++)
{
if (list[i][j][k] != 0)
{
finish = 0;
break;
}
}
// outside all the loops
return finish;
I think this is what you're asking for but if not please edit your question to clarify. I'm not sure if there is some technical name for this concept but the idea is to choose your initial truth value based on what's most efficient. Given you have a 15x15x15 array and a single non-zero value means false, it's much better to begin with true and break as soon as you encounter a value that makes your statement false. Trying to go in the other direction is far more complicated and far less efficient.
Maybe you can add your list[i][j][k] to a collection every time list[i][j][k]=0. Then at the end of your program, check for the collection's length. If it's of the right length, then terminate..

Best (fastest) way to find the number most frequently entered in C?

Well, I think the title basically explains my doubt. I will have n numbers to read, this n numbers go from 1 to x, where x is at most 105. What is the fastest (less possible time to run it) way to find out which number were inserted more times? That knowing that the number that appears most times appears more than half of the times.
What I've tried so far:
//for (1<=x<=10⁵)
int v[100000+1];
//multiple instances , ends when n = 0
while (scanf("%d", &n)&&n>0) {
zerofill(v);
for (i=0; i<n; i++) {
scanf("%d", &x);
v[x]++;
if (v[x]>n/2)
i=n;
}
printf("%d\n", x);
}
Zero-filling a array of x positions and increasing the position vector[x] and at the same time verifying if vector[x] is greater than n/2 it's not fast enough.
Any idea might help, thank you.
Observation: No need to care about amount of memory used.
The trivial solution of keeping a counter array is O(n) and you obviously can't get better than that. The fight is then about the constants and this is where a lot of details will play the game, including exactly what are the values of n and x, what kind of processor, what kind of architecture and so on.
On the other side this seems really the "knockout" problem, but that algorithm will need two passes over the data and an extra conditional, thus in practical terms in the computers I know it will be most probably slower than the array of counters solutions for a lot of n and x values.
The good point of the knockout solution is that you don't need to put a limit x on the values and you don't need any extra memory.
If you know already that there is a value with the absolute majority (and you simply need to find what is this value) then this could make it (but there are two conditionals in the inner loop):
initialize count = 0
loop over all elements
if count is 0 then set champion = element and count = 1
else if element != champion decrement count
else increment count
at the end of the loop your champion will be the value with the absolute majority of elements, if such a value is present.
But as said before I'd expect a trivial
for (int i=0,n=size; i<n; i++) {
if (++count[x[i]] > half) return x[i];
}
to be faster.
EDIT
After your edit seems you're really looking for the knockout algorithm, but caring about speed that's probably still the wrong question with modern computers (100000 elements is nothing even for a nail-sized single chip today).
I think you can create a max heap for the count of number you read,and use heap sort to find all the count which greater than n/2

use five point stencil to evaluate function with vector inputs and converge to maximum output value

I am familiar with iterative methods on paper, but MATLAB coding is relatively new to me and I cannot seem to find a way to code this.
In code language...
This is essentially what I have:
A = { [1;1] [2;1] [3;1] ... [33;1]
[1;2] [2;2] [3;2] ... [33;2]
... ... ... ... ....
[1;29] [2;29] [3;29] ... [33;29] }
... a 29x33 cell array of 2x1 column vectors, which I got from:
[X,Y] = meshgrid([1:33],[1:29])
A = squeeze(num2cell(permute(cat(3,X,Y),[3,1,2]),1))
[ Thanks to members of stackOverflow who helped me do this ]
I have a function that calls each of these column vectors and returns a single value. I want to institute a 2-D 5-point stencil method that evaluates a column vector and its 4 neighbors and finds the maximum value attained through the function out of those 5 column vectors.
i.e. if I was starting from the middle, the points evaluated would be :
1.
A{15,17}(1)
A{15,17}(2)
2.
A{14,17}(1)
A{14,17}(2)
3.
A{15,16}(1)
A{15,16}(2)
4.
A{16,17}(1)
A{16,17}(2)
5.
A{15,18}(1)
A{15,18}(2)
Out of these 5 points, the method would choose the one with the largest returned value from the function, move to that point, and rerun the method. This would continue on until a global maximum is reached. It's basically an iterative optimization method (albeit a primitive one). Note: I don't have access to the optimization toolbox.
Thanks a lot guys.
EDIT: sorry I didn't read the iterative part of your Q properly. Maybe someone else wants to use this as a template for a real answer, I'm too busy to do so now.
One solution using for loops (there might be a more elegant one):
overallmax=0;
for v=2:size(A,1)-1
for w=2:size(A,2)-1
% temp is the horizontal part of the "plus" stencil
temp=A((v-1):(v+1),w);
tmpmax=max(cat(1,temp{:}));
temp2=A(v,(w-1):(w+1));
% temp2 is the vertical part of the "plus" stencil
tmpmax2=max(cat(1,temp2{:}));
mxmx=max(tmpmax,tmpmax2);
if mxmx>overallmax
overallmax=mxmx;
end
end
end
But if you're just looking for max value, this is equivalent to:
maxoverall=max(cat(1,A{:}));

Solving problems recursively in C

Our professor gave us the following assignment:
A "correct" series is one in which the sum of its members equals to the index of its first member.
The program is supposed to find the length of the LONGEST "correct" series within a series of n numbers.
For example: if the input series would be arr[4]={1, 1, 0, 0}
the output (longest "correct" series) would be 3.
arr[0]=1. 0!=1 therefore the longest series here is 0.
arr[1]=1,and 1=1. but the following members also sum up to 1 as shown below:
1=arr[1]+arr[2]+arr[3] = 1+ 0 + 0, therefore the longest series here is 3.
The output in this example is 3.
This is what I have so far:
int solve(int arr[], int index, int length,int sum_so_far)
{
int maxwith,maxwithout;
if(index==length)
return 0;
maxwith = 1+ solve(arr,index+1,length,sum_so_far+arr[index]);
maxwithout = solve(arr,index+1,length,arr[index+1]);
if(sum_so_far+arr[index]==index)
if(maxwith>maxwithout)
return maxwith;
return maxwithout;
return 0;
}
int longestIndex(int arr[], int index,int length)
{
return solve(arr,0,length,0);
}
What am I doing wrong here?
We aren't supposed to us loops on this assignment.
Hmm, there are several problems with this program.
Most obvious, "return maxwithout; return 0;" should give a compile error: There's no way to get to that last return statement.
Second, you're recursing in to solve on the "maxwith" path until you reach the end of the array. Then you're going to recurse into maxwithout, hitting it for the first time with index=4. I don't think this is going to work.
Frankly, I don't think this problem really calls for recursion. THe most natural solution would be a nested loop:
for (int start=0;start<length;++start)
{
for (int end=start;end<length;++end)
{
// calculate the sum of arr[start]->arr[end] and compare to start
}
}
Or something to that effect.
Did the problem call for solving it with recursion, or was that just your first idea at a good solution?
Edit
Okay, so you have to use recursion. I guess the point of the lesson is to learn to use recursion, not necessarily to solve the problem in the most natural or efficient way. (Personally, I think the teacher should have come up with a problem where recursion was a natural solution, but I guess we're not here to critique the teacher today.)
I don't want to do your homework for you, but I'll give you a hint. You can use recursion to simulate a loop by putting the break condition at the beginning of the function and putting the recursive call at the end of the function with a +1 parameter. That is, instead of writing
for (int x=0;x<10;++x) { ... whatever ...}
you can write
void forx(int x)
{
if (x>=10)
return;
... whatever ...
forx(x+1);
}
So in this case I'd do something like:
void endloop(int start, int end)
{
if (end>=arrayLength)
return;
... work on running total ...
endloop(start, end+1);
}
void startloop(int start)
{
if (start>=arrayLength)
return;
endloop(start, start);
}
int main()
{
... setup ...
startloop(0);
... output ...
}
Parameter lists are not necessarily complete. As I say, I don't want to do your homework for you, just give you a hint to get started.
First, write a function that tests a series of given starting index and given length for the "sum of its members" condition. Then, write a second function which looks for the longest series within your array where only the starting index is given (looping over the sub-series length in decreasing order should do it); this function can call the first one. At last, write a third function looping over all starting indexes, calling function number two.
Oh wait, there is no recursion needed any more, so a lot of brain-twisting is gone ... :-)
It seems to me that the problem lies here:
if(sum_so_far+arr[index]==index)
You're comparing the sum so far with the current index, but you should be comparing it with the first index in the series. It seems to me that it would be better if you started with the last element of arr towards the first, instead of going in the natural order. That way you start summing elements up until the sum equals the current index.

Resources