# Trying to understand implied do loops

**URL:** <https://fortran-lang.discourse.group/t/trying-to-understand-implied-do-loops/4745>\
**Category:** Help\
**Created:** [November 15, 2022, 11:26pm UTC](https://fortran-lang.discourse.group/t/trying-to-understand-implied-do-loops/4745 "2022-11-15T23:26:27Z")\
**Posts on this page:** 9\
**Page:** 2

<div class="post-metadata">

**Author:** ![msz59](https://avatars.discourse-cdn.com/v4/letter/m/3d9bf3/32.png) [@msz59](https://fortran-lang.discourse.group/u/msz59)\
**Post date:** [November 16, 2022, 7:43pm UTC](https://fortran-lang.discourse.group/t/trying-to-understand-implied-do-loops/4745/21 "2022-11-16T19:43:35Z")

</div>

I have just cited the OP’s code 🙂

The integer kind for variables indexing the arrays/string could probably be just plain default.  
`int64` makes sense for the `product` calculations.

---

<div class="post-metadata">

**Author:** ![Aurelius\_Nero](https://avatars.discourse-cdn.com/v4/letter/a/a87d85/32.png) [@Aurelius\_Nero](https://fortran-lang.discourse.group/u/Aurelius_Nero)\
**Post date:** [November 16, 2022, 7:59pm UTC](https://fortran-lang.discourse.group/t/trying-to-understand-implied-do-loops/4745/22 "2022-11-16T19:59:53Z")

</div>

> [@msz59](#):
>
> The integer kind for variables indexing the arrays/string could probably be just plain default.  
> `int64` makes sense for the `product` calculations.

True, but I feel like I don’t trust the compiler to fully make the conversion if I just use int64 for the product. If I mix kinds for the integer type, would that be cause for concern ?

> [@msz59](#):
>
> I have just cited the OP’s code 🙂

Where did you cite it 😃

---

<div class="post-metadata">

**Author:** ![msz59](https://avatars.discourse-cdn.com/v4/letter/m/3d9bf3/32.png) [@msz59](https://fortran-lang.discourse.group/u/msz59)\
**Post date:** [November 16, 2022, 8:10pm UTC](https://fortran-lang.discourse.group/t/trying-to-understand-implied-do-loops/4745/23 "2022-11-16T20:10:17Z")

</div>

Sorry, I should have made a regular quote, not just the code snippet.

> [@Aurelius\_Nero](#):
>
> ```auto
> ! [...]
> array_pos = array_pos + INT(1, KIND=int64) ! <== HERE
> parser_stop_var = array_pos ! <== and HERE
> 
> END DO
> 
> PRINT *, " "
> PRINT *, "The greatest product is "
> PRINT *, greatest_product
> 
> END PROGRAM pr8
> 
> ```

---

<div class="post-metadata">

**Author:** ![Aurelius\_Nero](https://avatars.discourse-cdn.com/v4/letter/a/a87d85/32.png) [@Aurelius\_Nero](https://fortran-lang.discourse.group/u/Aurelius_Nero)\
**Post date:** [November 16, 2022, 8:16pm UTC](https://fortran-lang.discourse.group/t/trying-to-understand-implied-do-loops/4745/24 "2022-11-16T20:16:23Z")

</div>

Thank you 👍

---

<div class="post-metadata">

**Author:** ![msz59](https://avatars.discourse-cdn.com/v4/letter/m/3d9bf3/32.png) [@msz59](https://fortran-lang.discourse.group/u/msz59)\
**Post date:** [November 16, 2022, 8:43pm UTC](https://fortran-lang.discourse.group/t/trying-to-understand-implied-do-loops/4745/25 "2022-11-16T20:43:51Z")

</div>

> [@Aurelius\_Nero](#):
>
> If I mix kinds for the integer type, would that be cause for concern ?

Not unless you would want to process input files greater than 2GB 🙂 Otherwise  
`array_pos,parser_stop_var, number_array_size, i` - could be default `integer`  
`greatest_product, product_tmp, number_array_tmp(:),number_array_best(:)` - int64

The code could be further improved in terms of speed by noticing that the two _adjacent_ products are related by  
\prod\_{i+1}^{i+m+1}N\_i = (\prod\_{i}^{i+m}N\_i)/N\_{i}\cdot N\_{i+m+1}\quad if N\_{i}\neq 0

It would speed up the code if the whole string was first read into array, thus avoiding repeated `read`s of the same characters.

One should also be aware of possible overflow of `product` which is easy to get into with longer sub-arrays but not that easy to detect/overcome.

---

<div class="post-metadata">

**Author:** ![RonShepard](https://avatars.discourse-cdn.com/v4/letter/r/a3d4f5/32.png) [@RonShepard](https://fortran-lang.discourse.group/u/RonShepard)\
**Post date:** [November 16, 2022, 11:30pm UTC](https://fortran-lang.discourse.group/t/trying-to-understand-implied-do-loops/4745/26 "2022-11-16T23:30:59Z")

</div>

> [@msz59](#):
>
> One should also be aware of possible overflow of `product` which is easy to get into with longer sub-arrays but not that easy to detect/overcome.

Something like this may help:

```auto
integer function safe_mult( i, j )
   implicit none
   integer, intent(in) :: i, j
   safe_mult = 0
   if ( i == 0 ) return
   if ( j == 0 ) return
   if ( abs(j) > huge(i)/abs(i) ) error stop 'i*j overflow'
   safe_mult = i * j
   return
end function safe_mult

```

---

<div class="post-metadata">

**Author:** ![Aurelius\_Nero](https://avatars.discourse-cdn.com/v4/letter/a/a87d85/32.png) [@Aurelius\_Nero](https://fortran-lang.discourse.group/u/Aurelius_Nero)\
**Post date:** [November 17, 2022, 8:01pm UTC](https://fortran-lang.discourse.group/t/trying-to-understand-implied-do-loops/4745/27 "2022-11-17T20:01:39Z")

</div>

Thank you for this. It’s very useful

---

<div class="post-metadata">

**Author:** ![msz59](https://avatars.discourse-cdn.com/v4/letter/m/3d9bf3/32.png) [@msz59](https://fortran-lang.discourse.group/u/msz59)\
**Post date:** [November 17, 2022, 8:34pm UTC](https://fortran-lang.discourse.group/t/trying-to-understand-implied-do-loops/4745/28 "2022-11-17T20:34:05Z")

</div>

@RonShepard’s `safe_mult` looks good as a general solution to the integer overflow multiplication problem. But for OP’s problem it is less applicable.

1. You could not use `product` intrinsic function
2. If you do not use `product`, doing the multiplications yourself, for the specific problem being solved (non-negative results, multiplication by a number less or equal to 9), it would be sufficient to check (before every multiplication) if the current product value is less than `huge(1_int64)/9_int64` - that value could be defined as a parameter.  
2a. Also, using regular multiplications instead of `product` function would make the computing of the _rolling product_ by _dividing-out_ its first element and _multiplying-in_ the new last one.

---

<div class="post-metadata">

**Author:** ![CRquantum](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/crquantum/32/730_2.png) [@CRquantum](https://fortran-lang.discourse.group/u/CRquantum)\
**Post date:** [November 18, 2022, 2:26am UTC](https://fortran-lang.discourse.group/t/trying-to-understand-implied-do-loops/4745/29 "2022-11-18T02:26:16Z")

</div>

> [@msz59](#):
>
> The code could be further improved in terms of speed by noticing that the two _adjacent_ products are related by  
> \prod\_{i+1}^{i+m+1}N\_i = (\prod\_{i}^{i+m}N\_i)/N\_{i}\cdot N\_{i+m+1}\quad ∏i+m+1i+1Ni=(∏i+miNi)/Ni⋅Ni+m+1\prod\_{i+1}^{i+m+1}N\_i = (\prod\_{i}^{i+m}N\_i)/N\_{i}\cdot N\_{i+m+1}\quad if N\_{i}\neq 0 Ni≠0N\_{i}\neq 0  
> It would speed up the code if the whole string was first read into array, thus avoiding repeated `read`s of the same characters.
> 
> One should also be aware of possible overflow of `product` which is easy to get into with longer sub-arrays but not that easy to detect/overcome.

Right. Another thing to prevent overflow could be that, perhaps instead of calculating that big product thing, can calculate the log of that instead, \log \prod\_{i=1}^{m}N\_i = \sum\_{i=1}^{m} \log(N\_i) , especially if the N\_i = \exp(...), so the product is converted to summation, and in the end convert it back.

[Previous page](https://fortran-lang.discourse.group/t/trying-to-understand-implied-do-loops/4745.md?page=1)
