# How can I solve this equation which has condition?

**URL:** <https://fortran-lang.discourse.group/t/how-can-i-solve-this-equation-which-has-condition/1669>\
**Category:** Homework\
**Created:** [August 11, 2021, 7:30am UTC](https://fortran-lang.discourse.group/t/how-can-i-solve-this-equation-which-has-condition/1669 "2021-08-11T07:30:26Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![haidangwy](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/haidangwy/32/732_2.png) [@haidangwy](https://fortran-lang.discourse.group/u/haidangwy)\
**Post date:** [August 11, 2021, 7:30am UTC](https://fortran-lang.discourse.group/t/how-can-i-solve-this-equation-which-has-condition/1669/1 "2021-08-11T07:30:26Z")

</div>

Hi everyone!. I’m a newbie in Fortran.  
I try to solve the equation  
F(x)=a/x if x \> 4 and F(x) = (a/b).(3-x^2) if x \<= 4  
with a,b are constants that I can change any real number  
I use bisection method but in this case, I don’t know how to declare the function. Here is my code

> program bisec  
> implicit none  
> integer, parameter:: n=1000  
> double precision f,x1,x2,eps  
> double precision nroots(n)  
> integer i,nroots  
> exteral f  
> x1=0.0  
> x2=10.0 ! I change this number.  
> eps=1.0e-7  
> call bisection(f,x1,x2,eps,n,roots,nroots)  
> if (nroots==0) then  
> write(_,_) ‘no root found’  
> stop  
> end if  
> write(_,_) ‘roots of equation are’  
> do i=1,nroots,1  
> write (_,_) i, root(i)  
> end do  
> end program bisec
> 
> function f  
> implicit none  
> double precision f,x  
> if (x\>4.0) then f = a/x  
> else x \<4.0 then f=(a/b)\*(3-x\*\*2.0)  
> end function  
> subroutine bisection(f,x1,x2,esp,n,roots,nroots)  
> implicit none  
> integer, parameter:: n=1000  
> double precision f,x1,x2,eps,roots(n)  
> double precision a,b,c,dx,root  
> integer n,i,j,nroots  
> interger, parameter::sk =200  
> dx = (x2-x1)/n  
> nroots=0  
> do j =1,n  
> a=x1+(j-1)\*dx  
> b=a+dx  
> if (f(a)\*f(b))\>0) cycle  
> do i = 1, sk  
> c=(b+a)/2.0  
> if (f(c).f(a)\<=0) then  
> b=c  
> else  
> a=c  
> end if  
> if (abs(a-b)\<=eps) exit  
> end do  
> root=(a+b)/2.0  
> if (abs(f(root)\<1.0) then  
> nroots=nroots+1  
> Roots(nroots)= root  
> end if  
> end do  
> end subroutine bisection

I know I get trouble in declare the funtion, please help me!

---

<div class="post-metadata">

**Author:** ![Arjen](https://avatars.discourse-cdn.com/v4/letter/a/b9bd4f/32.png) [@Arjen](https://fortran-lang.discourse.group/u/Arjen)\
**Post date:** [August 11, 2021, 11:19am UTC](https://fortran-lang.discourse.group/t/how-can-i-solve-this-equation-which-has-condition/1669/2 "2021-08-11T11:19:14Z")

</div>

I have improved your program wrt the syntax and some typos. The most important changes are documented in the comments. There are much more possible improvements, for instance the use of “double precision” and putting the bisect routine in a module and so on, but this should get you started.

```auto
! bisect.f90 --
! Improving sample program
!
program bisec
    implicit none
    integer, parameter :: n=1000
    double precision :: x1,x2,eps
    double precision :: roots(n)

    double precision :: a, b !<== these were not defined

    integer i, nroots

    a = 1.0 !<== values will be available in the function f,
    b = 2.0 !<== because f is an internal function now.

    x1=0.0
    x2=10.0 ! I change this number.
    eps=1.0e-7
    call bisection(f,x1,x2,eps,n,roots,nroots)
    if (nroots==0) then
        write(*,*) 'no root found' !<== plain quotes, not "smart" quotes
        stop
    end if
    write(*,*) 'roots of equation are'
    do i=1,nroots,1
        write (*,*) i, roots(i)
    end do

contains

! Using a so-called internal routine/function, then the variables a and b
! are taken from the encompassing program. Avoids having to pass them
! explicitly via the routine "bisect".

function f( x ) !<== argument should be added
    implicit none
    double precision f,x

    if (x>4.0) then
        f = a/x
    else
        f=(a/b)*(3-x**2.0)
    endif
end function

end program bisec

subroutine bisection(f,x1,x2,eps,n,roots,nroots)
    implicit none
    double precision f,x1,x2,eps,roots(n)
    double precision a,b,c,dx,root
    integer n,i,j,nroots
    integer, parameter::sk =200

    dx = (x2-x1)/n
    nroots=0
    do j =1,n
        a=x1+(j-1)*dx
        b=a+dx
        if (f(a)*f(b) > 0) cycle
        do i = 1, sk
            c=(b+a)/2.0
            if (f(c)*f(a) <= 0) then
                b=c
            else
                a=c
            end if
            if (abs(a-b) <= eps) exit
        end do
        root=(a+b)/2.0
        if (abs(f(root)) < 1.0) then
            nroots=nroots+1
            Roots(nroots)= root
        end if
    end do
end subroutine bisection

```

---

<div class="post-metadata">

**Author:** ![haidangwy](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/haidangwy/32/732_2.png) [@haidangwy](https://fortran-lang.discourse.group/u/haidangwy)\
**Post date:** [August 11, 2021, 3:36pm UTC](https://fortran-lang.discourse.group/t/how-can-i-solve-this-equation-which-has-condition/1669/3 "2021-08-11T15:36:09Z")

</div>

thank you for your nice comment. I learn a lot form it

---

<div class="post-metadata">

**Author:** ![Arjen](https://avatars.discourse-cdn.com/v4/letter/a/b9bd4f/32.png) [@Arjen](https://fortran-lang.discourse.group/u/Arjen)\
**Post date:** [August 11, 2021, 3:37pm UTC](https://fortran-lang.discourse.group/t/how-can-i-solve-this-equation-which-has-condition/1669/4 "2021-08-11T15:37:42Z")

</div>

You’re welcome 😉

---

<div class="post-metadata">

**Author:** ![haidangwy](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/haidangwy/32/732_2.png) [@haidangwy](https://fortran-lang.discourse.group/u/haidangwy)\
**Post date:** [August 11, 2021, 4:05pm UTC](https://fortran-lang.discourse.group/t/how-can-i-solve-this-equation-which-has-condition/1669/5 "2021-08-11T16:05:33Z")

</div>

I also thinkk there is another way to solve this. But I still don’t make it run. I think if i make an array 1D, and put the number in this f function. if f(xi) is near 0 with small error then I choose it which means my roots. Are there any ways to solve this?

---

<div class="post-metadata">

**Author:** ![milancurcic](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/milancurcic/32/2_2.png) [@milancurcic](https://fortran-lang.discourse.group/u/milancurcic)\
**Post date:** [August 11, 2021, 4:20pm UTC](https://fortran-lang.discourse.group/t/how-can-i-solve-this-equation-which-has-condition/1669/6 "2021-08-11T16:20:31Z")

</div>

Welcome, @haidangwy!

---

<div class="post-metadata">

**Author:** ![haidangwy](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/haidangwy/32/732_2.png) [@haidangwy](https://fortran-lang.discourse.group/u/haidangwy)\
**Post date:** [August 12, 2021, 7:11am UTC](https://fortran-lang.discourse.group/t/how-can-i-solve-this-equation-which-has-condition/1669/7 "2021-08-12T07:11:48Z")

</div>

I try to run this equation  
f(x)=0 but there is a condition  
if x \<=5.84 we have  
f=(-50/(1+(exp(x-5.84)/0.5))+**(12.33\*(3.0-x^2/34.11)**+1.41/(x^2.0)  
if x \>5.84 we have  
f = f=(-50/(1+(exp(x-5.84)/0.5))+ **144.0/x** +1.41/(x^2.0)  
it just have the difference in this part.  
When I declare the function I recieve

> f is not a variable

Here is my code at the declaration part

```auto
function f(x)
if (x<=5.84) then
f=(-50/(1.0+exp(x-5.84)/0.5))+(12.33*(3.0-x**2/34.1056)+1.41/(x**2)
else
f=(-50/(1.0+exp(x-5.84)/0.5))+144/x**2+1.41/(x**2)
end if
end function f(x)

```

---

<div class="post-metadata">

**Author:** ![Arjen](https://avatars.discourse-cdn.com/v4/letter/a/b9bd4f/32.png) [@Arjen](https://fortran-lang.discourse.group/u/Arjen)\
**Post date:** [August 12, 2021, 7:23am UTC](https://fortran-lang.discourse.group/t/how-can-i-solve-this-equation-which-has-condition/1669/8 "2021-08-12T07:23:45Z")

</div>

Hm, you do not define the type of the function. Can you post the complete program, as it is not clear from your message from what point in the code the error originates.

---

<div class="post-metadata">

**Author:** ![nbehrnd](https://avatars.discourse-cdn.com/v4/letter/n/e0b2c6/32.png) [@nbehrnd](https://fortran-lang.discourse.group/u/nbehrnd)\
**Post date:** [August 12, 2021, 7:47am UTC](https://fortran-lang.discourse.group/t/how-can-i-solve-this-equation-which-has-condition/1669/9 "2021-08-12T07:47:28Z")

</div>

As a meta comment on the appearance of your codes shared, I would like to suggest to use indentations when it comes to if-clauses, do-iterations, etc.

Contrasting to other languages (e.g., Python) indentation (probably _most often_) is functional irrelevant to modern Fortran. However, this form to structure code (cf. Arjen’s improvement of `bisect.f90`) visually into parts sharing a task/within a logical step helps to read the code. It only is a matter of complexity of the code written and time since initial design of the program that this equally may be helpful to you, too.

If the environment you use does not support this by default, I suggest to pass your code to a code formatter. An equivalent to `yapf3` and `black` in Python is e.g., Peter Seewald’s [fprettify](https://github.com/pseewald/fprettify), which recognizes a selection of these small units and indents them accordingly (this includes nested loops). While probably not designed to be a code linter (like `pylint`), loops not properly terminated are easily identified in `fprettify`'s output, too.

---

<div class="post-metadata">

**Author:** ![haidangwy](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/haidangwy/32/732_2.png) [@haidangwy](https://fortran-lang.discourse.group/u/haidangwy)\
**Post date:** [August 12, 2021, 7:57am UTC](https://fortran-lang.discourse.group/t/how-can-i-solve-this-equation-which-has-condition/1669/10 "2021-08-12T07:57:55Z")

</div>

![image](https://global.discourse-cdn.com/free1/uploads/fortran_lang/original/1X/9c0962850faafcf7d8b2056864fad6d1fe7be787.png)

And here is my code:

```auto
program solvingpr1
implicit real*8(a-h,o-z)
integer, parameter:: n=1000
double precision ::x1,x2,esp
double precision:: roots(n)
integer i,nroots
x1=0.0
x2=20.0
eps=1.0e-7
call solving(f,x1,x2,eps,n,roots,nroots)
if (nroots==0) then
write(*,*) 'has no root' 
stop
end if
write (*,*) 'roots of this equation are'
do i=1,nroots,1
write(*,*) i, roots(i), f(roots(i))
end do
contains
function f(x)
implicit real*8(a-h,o-z)
double precision f,x
f=(-50/(1.0+exp(x-5.84)/0.5))+(12.33*(3.0-x**2/34.1056)+1.41/(x**2)
else
f=(-50/(1.0+exp(x-5.84)/0.5))+144/x**2+1.41/(x**2)
endif
end function f(x)

end program solvingpr1

!----------------------------------------------subroutine
subroutine solving(f,x1,x2,esp,n,roots,nroots)
implicit none
integer, parameter:: n=1000
double precision f,x1,x2,eps,roots(n)
double precision a,b,c,dx,root
integer n,i,j,nroots
interger, parameter::sk =200
dx = (x2-x1)/n
nroots=0
do j =1,n
a=x1+(j-1)*dx
b=a+dx
if (f(a)*f(b))>0) cycle
do i = 1, sk
c=(b+a)/2.0
if (f(c).f(a)<=0) then
b=c
else
a=c
end if
if (abs(a-b)<=eps) exit
end do
root=(a+b)/2.0
if (abs(f(root)<1.0) then
nroots=nroots+1
Roots(nroots)= root
end if
end do
end subroutine solving

```

---

<div class="post-metadata">

**Author:** ![haidangwy](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/haidangwy/32/732_2.png) [@haidangwy](https://fortran-lang.discourse.group/u/haidangwy)\
**Post date:** [August 12, 2021, 8:04am UTC](https://fortran-lang.discourse.group/t/how-can-i-solve-this-equation-which-has-condition/1669/11 "2021-08-12T08:04:26Z")

</div>

I think I could solve this problem by the way if x=x1 we have f(x1)=a  
then i subtract f(x1)-4.290 then I compare the result with a value which I can accept (eps = 1e-07). and then infer to the root :).  
I repeat this for many time. Is it possible?

---

<div class="post-metadata">

**Author:** ![Arjen](https://avatars.discourse-cdn.com/v4/letter/a/b9bd4f/32.png) [@Arjen](https://fortran-lang.discourse.group/u/Arjen)\
**Post date:** [August 12, 2021, 8:11am UTC](https://fortran-lang.discourse.group/t/how-can-i-solve-this-equation-which-has-condition/1669/12 "2021-08-12T08:11:31Z")

</div>

Thanks for posting that code, but:

- Pick up on the explicit advice by @nbehrnd - it really really helps to understand the code!
- Do not use “implicit real\*8(a-h,o-z)” - it is a sure method to let simple bugs into your code. Use “implicit none” instead. It forces you to declare all variables, but it prevents stupid mistakes like typing “o” instead of “0”, simply because you did not declare “o” to be a variable. (And do not use “o” as a variable name, by the way)

Looking at you code: “interger” is not a Fortran keyword. And the function f in solving is not defined as a function but as a variable. Hence the call is inconsistent.

---

<div class="post-metadata">

**Author:** ![haidangwy](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/haidangwy/32/732_2.png) [@haidangwy](https://fortran-lang.discourse.group/u/haidangwy)\
**Post date:** [August 12, 2021, 9:44am UTC](https://fortran-lang.discourse.group/t/how-can-i-solve-this-equation-which-has-condition/1669/13 "2021-08-12T09:44:39Z")

</div>

thank you very much 🙂 for your nice comments. It really helps me!

---

<div class="post-metadata">

**Author:** ![Beliavsky](https://avatars.discourse-cdn.com/v4/letter/b/ba8739/32.png) [@Beliavsky](https://fortran-lang.discourse.group/u/Beliavsky)\
**Post date:** [August 12, 2021, 11:02am UTC](https://fortran-lang.discourse.group/t/how-can-i-solve-this-equation-which-has-condition/1669/14 "2021-08-12T11:02:18Z")

</div>

It is good to compile with picky compiler options that point out problems in code that is still legal. With gfortran I suggest `-Wall -Wextra -Wconversion-extra` For a snippet of your code

```auto
implicit none
double precision :: x2,eps
x2 = 20.0
print*,x2
end

```

`gfortran -Wconversion-extra` says

```auto
xxdouble.f90:3:3:

    3 | x2=20.0
      | 1
Warning: Conversion from 'REAL(4)' to 'REAL(8)' at (1) [-Wconversion-extra]
xxdouble.f90:4:4:

    4 | eps=1.0e-7
      | 1
Warning: Conversion from 'REAL(4)' to 'REAL(8)' at (1) [-Wconversion-extra]

```

The [Quickstart Fortran Tutorial](https://fortran-lang.org/learn/quickstart/variables), which I suggest reading, gives the example (slightly abbreviated)

```auto
program float
use, intrinsic :: iso_fortran_env, only: dp=>real64
implicit none
real(dp) :: float64
float64 = 1.0_dp ! Explicit suffix for literal constants
end program float

```

and gives the advice, which I endorse,

> Always use a `kind` suffix for floating-point literal constants.

P.S. Not directed to OP. Should not gfortran with -Wall -Wextra include -Wconversion-extra ? Does FPM warn by default about double precision variables set to single precision literal constants?

---

<div class="post-metadata">

**Author:** ![FortranFan](https://avatars.discourse-cdn.com/v4/letter/f/96bed5/32.png) [@FortranFan](https://fortran-lang.discourse.group/u/FortranFan)\
**Post date:** [August 12, 2021, 12:51pm UTC](https://fortran-lang.discourse.group/t/how-can-i-solve-this-equation-which-has-condition/1669/15 "2021-08-12T12:51:00Z")

</div>

@haidangwy ,

An inquiry first: are you a student? and is this a homework problem?

If yes, I suggest studying the numerical computing advancements related to the works of Dekker, Brent et al. on finding zeroes of functions c.f. [https://blogs.mathworks.com/cleve/2015/10/26/zeroin-part-2-brents-version/#d354b12f-235d-474e-be05-d4dba9fa6fcc](https://blogs.mathworks.com/cleve/2015/10/26/zeroin-part-2-brents-version/#d354b12f-235d-474e-be05-d4dba9fa6fcc)

---

<div class="post-metadata">

**Author:** ![haidangwy](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/haidangwy/32/732_2.png) [@haidangwy](https://fortran-lang.discourse.group/u/haidangwy)\
**Post date:** [August 12, 2021, 2:26pm UTC](https://fortran-lang.discourse.group/t/how-can-i-solve-this-equation-which-has-condition/1669/16 "2021-08-12T14:26:33Z")

</div>

Thanks Mr.Beliavsky. I’m a student. This is my assignment. I try to write a code for myself with Fortran.  
Thank your for your link. I’m going to read this.

---

<div class="post-metadata">

**Author:** ![haidangwy](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/haidangwy/32/732_2.png) [@haidangwy](https://fortran-lang.discourse.group/u/haidangwy)\
**Post date:** [August 13, 2021, 7:31am UTC](https://fortran-lang.discourse.group/t/how-can-i-solve-this-equation-which-has-condition/1669/17 "2021-08-13T07:31:58Z")

</div>

I want to thank everybody for helping me 😉

---

<div class="post-metadata">

**Author:** ![haidangwy](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/haidangwy/32/732_2.png) [@haidangwy](https://fortran-lang.discourse.group/u/haidangwy)\
**Post date:** [August 13, 2021, 7:39am UTC](https://fortran-lang.discourse.group/t/how-can-i-solve-this-equation-which-has-condition/1669/18 "2021-08-13T07:39:42Z")

</div>

It’s really interesting. When I solved some problem then new problems come. Today I’ve got a new problem that I want to take my roots from this equation. Let’s say I have 3 roots: 1,2,3. I need to assign them in a,b,c for the further calculation in this program.

```auto
a= root(1)
b= root(2)
c= root(3)

```

How can I do it?

---

<div class="post-metadata">

**Author:** ![Arjen](https://avatars.discourse-cdn.com/v4/letter/a/b9bd4f/32.png) [@Arjen](https://fortran-lang.discourse.group/u/Arjen)\
**Post date:** [August 13, 2021, 7:53am UTC](https://fortran-lang.discourse.group/t/how-can-i-solve-this-equation-which-has-condition/1669/19 "2021-08-13T07:53:18Z")

</div>

Well, assuming your solution routine returns multiple roots in an array “root” (as was the case in your first post), then that is exactly the syntax you need.

---

<div class="post-metadata">

**Author:** ![haidangwy](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/haidangwy/32/732_2.png) [@haidangwy](https://fortran-lang.discourse.group/u/haidangwy)\
**Post date:** [August 13, 2021, 7:54am UTC](https://fortran-lang.discourse.group/t/how-can-i-solve-this-equation-which-has-condition/1669/20 "2021-08-13T07:54:27Z")

</div>

amazing. I did it. I’m happy about it 🙂

[Next page](https://fortran-lang.discourse.group/t/how-can-i-solve-this-equation-which-has-condition/1669.md?page=2)
