Time each iterations of For Loop in Julia? - loops

Given a for loop, is there some macro/function that times each iteration of the loop, and returns this info as a tuple or array (or similar)? Would there be any way to assign such tuple or array to a variable (for example, I am not sure how to assign output of #time macro to a variable). I am aware of the #timed macro, but not sure how to extract the tuple that #timed gives/assign to variable. Below is an example of a for loop where each iteration might be timed?
for x=1:10
println("$x is my number.")
end

Like this?
function timeloop(n)
tvec = zeros(n)
for x = 1:n
t = #elapsed println("$x is my number.")
tvec[x] = t
end
tvec
end
timeloop(9)
1 is my number.
2 is my number.
3 is my number.
4 is my number.
5 is my number.
6 is my number.
7 is my number.
8 is my number.
9 is my number.
9-element Vector{Float64}:
0.0002649
0.0001195
0.0001018
9.44e-5
8.25e-5
6.8e-5
8.52e-5
7.39e-5
8.5e-5
As per Julia help, #elapsed is a macro to evaluate an expression, discarding the resulting value, instead returning the number of seconds it took to execute as a floating-point number.
For timing multi-line expressions/statements, use the t = #elapsed begin .. end form.

Related

How to iterate each element of an array over a given range in Matlab?

I have a function that outputs an integer based on a 9 x 1 array. I want to check the functions output for various array values, so ideally I would like to iterate each element of the array in the range (0,3). Is there a simpler way to do this than having 9 nested for loops?
Note that you have 3^9 arrangement. If you had a function that can attribute the numbers 1 to 3^9 to each combination, you could do a single loop.
for i=1:3^9
current_array = arrangement_no(i);
test_function(current_array);
end
To define this function, basically convert to base 3 each number, take the digits and add one. I'll give an example for an array of size 3 with entries in the range 0:2 (try this first if you can).
function current_array = arrangement_no(i)
current_array = zeros(1,3)
for j = 1:3
current_array(end+1-j) = mod(i,3);
i= floor(i/3);
end
end

The possible combinations of n digits

I want to write a C function that takes one integer as input and gives me all possible combinations using that much digits.
For example:
cases(3);
Output:
123 132 213 231 312 321
It uses the first three digits to create a three digit number, notice that I need that to work for any number of digits n.
Notice that cases(3) has 3! = 6 results.
So cases(4) has 4! = 24 results and so on.
I actually don't even know how to even approach this problem so any help is appreciated.
Recursion for the win :-)
the combinations of 1 digit is 1
the combinations of N digits is the recursive combinations of N - 1 digits with N added at every possible place
try to think of an algorithmn before you actually try to write the code.
Think of how you solved the Problem in your head when you wrote your desired output down. just find a systematic way to do this: for example you start with the lowest number and then check for the other numbers...
I have written the logic and code in python
#n digit number as input converted into list
m=int(input("enter number of digits:"))
f=[]
for i in range(1,m+1):
f.append(str(i))
#dynamic array for dynamic for loop inside recursion
a=[0 for k in range(len(f))]
c=[]#list which is to be used for append for digits
ans=[]# result in which the
# recursion for if loop inside for loop
#1st argument is fixed inside the loop
#2nd argument will be decreasing
def conditn(k,m):
if(m==0):
return 1
if(m==1):
if(a[k]!=a[0]):
return 1
if(a[k]!=a[m-1] and conditn(k,m-1)):
return 1
#recursion for for loop
#1st argument y is the length of the number
#2nd argument is for initialization for the varible to be used in for loop
#3rd argument is passing the list c
def loop(y, n,c):
if n<y-1:
#recursion until just befor the last for loop
for a[n] in range(y):
if(conditn(n,n)):
loop(y, n + 1,c)
else:
# last for loop
if(n==y-1):
for a[n] in range(y):
#last recursion of condition
if(conditn(n,n)):
#concatinating the individual number
concat=""
for i in range(y):
concat+=f[a[i]]+""
c.append(concat)
#returning the list of result for n digit number
return c
#printing the list of numbers after method call which has recursion within
#set is used used to convert any of the iterable to the
#distinct element and sorted sequence of iterable elements,
for j in (loop(len(f),0,c)):
print(j)

Loop through an array while summing the output

I am trying to use a for loop and then sum all of the outputs. I know this is a basic question, but I am not sure if I should be trying to solve this within the loop or using another array.
For example:
for i in 1..100
if foo / 2 == 0
#find the sum of all outputs
end
end
Try this:
(2..100).step(2).inject(:+) #=> 2550
Or:
2.step(100,2).inject(:+) #=> 2550
You can use sum instead of inject(:+) from Ruby 2.4+
I'm not entirely sure what you're asking, but my initial understanding is that you want to sum all of the numbers in a range (1..100) that meet a specific condition. In this case, something divided by 2 cannot equal zero aside from zero itself. I'm wondering if you meant %2, in which case, you're asking to sum all the even numbers in the range 1..100. This can be accomplished by doing the following.
(1..100).select {|x| x if x.even?}.reduce(:+)
Effectively, you want to enumerate over a range and select only the numbers that meet your condition, as specified in the block. Calling reduce and passing it an accumulator.

Assigning values of an array in a loop

In my code:
DO i=1,numJog,1
IF(val(i) .EQV. .TRUE.)THEN
DO j=1,contVenc,1
result(j) = i
END DO
END IF
END DO
Where val is a logical array, and result is a integer array.
For example, if val is:
F
T
F
T
Then, i=2 and i=4.
But the result array just write 4 twice. For example:
DO i=1,contVenc,1
WRITE(*,*) result(i)
END DO
The result is:
4
4
Instead of
2
4
If I make some changes in my code like:
DO i=1,numJog,1
IF(val(i) .EQV. .TRUE.)THEN
WRITE(*,*) i
END IF
END DO
The result is:
2
4
As I wanted.
Conclusion, I think this second loop is causing this problem.
Yes, your second loop is at fault here. You haven't said what contVenc is, but it crucially doesn't change at any point in the fragment you have there. That just means that the same elements of result are being assigned to whenever you have a .TRUE. in val.
In your case they are both set to 2 for the first .TRUE. and are then both set to 4 for the second.
You are more likely to mean something like (with extra tidying):
j = 0
DO i=1,numJog
IF (val(i)) THEN
j = j+1 ! Test this as a bound
result(j) = i
END IF
END DO
But then, I'd just use PACK. Your intended loop has the same effect as
result(1:COUNT(val(1:numJog))) = PACK([(i,i=1,numJog)], val(1:numJog))
Again hoping that result is large enough.
That said, if numJog is just the size of the array val (that is, you aren't just doing this on a sub-array) then, as High Performance Mark comments,
result(1:COUNT(val)) = PACK([(i,i=1,SIZE(val))], val)
avoids tracking this size separately.
Finally, with result an allocatable (Fortran 2003) array you needn't even (but still can) worry about counting the number of wanted indices and that the array is sufficiently large:
result = PACK([(i,i=1,SIZE(val))], val)

Problem creating a frequency array of a given array

I am trying to create a frequency array of a given array on Fortran 95. For instance if I have an array (\1 2 4 2 4 2 5), the frequency array should be the number of times each item appears; (\1 3 2 3 2 3 1). So because there are only 1 of 5s in the original array, the last entry in the new array is 1 and because there are 3 of 2s in the original array, the corresponding entries on the new array is a 2.
Below is a sample of the code I have, but I keep getting errors. I was wondering if anyone would be willing to give me some guidance and help on what I could be doing wrong. It would be very much appreciated.
I haven't included the part of the code that generates my original array because I'm pretty sure it is correct so here is just the subroutine for the frequency array. Also the original array was sorted in ascending order outside this subroutine. Perhaps I didn't pass the original array, num(i) correctly??
INTEGER, DIMENSION(100)::num(100)
INTEGER, DIMENSION(100)::freq(100)
INTEGER:: i=0, k=0, numinteger, count=0
CALL FreqArray(num, numinteger,freq)
SUBROUTINE FreqArray(num, numinteger, freq)
INTEGER, INTENT(IN):: num(100), numinteger
INTEGER, INTENT(OUT):: freq(100)
DO i=1,9
count=0
DO k=1, numinteger
IF (num(k)==i)THEN
count=count+1
END IF
END DO
freq(i)=count
END DO
PRINT*, "Frequency of Digits"
PRINT*, " "
WRITE(*,'(1X,A,T35,A)'),"Digit","Frequency"
WRITE(*,'(1X,I1,T35,I1)'),num(i),freq(i)
END SUBROUTINE
Thanks so much for your time.
I guess that the "(9)" is overriding the "DIMENSION(100)" making "freq" an array of length 9. Thus for the third argument the actual argument is length 9, while the dummy is length 100. Which causes your error message "actual argument ... is smaller than dummy size".
Other suggestions: you could make the subroutine more general using declarations "..., dimension (:) :: num". Then use the "size" intrinsic to determine the size of the num. freq could be fixed to 9 since there are always 9 digits.
With regards to your display issue, I suspect that you meant to have a loop around
WRITE(*,'(1X,I1,T35,I1)'),num(i),freq(i)

Resources