Novice tries using AI code generators

Having seen a number of posts in this forum and elsewhere wherein the use of AI code generators was discussed, I decided to step into the swamp today. Some readers may find my experience interesting, and a smaller number may even find it useful.

My first attempt was to ask for Fortran code to solve a cubic equation with real coefficients. The results (ChatGPT, Gemini) were disappointing. Sometimes the code contained syntax errors, and sometimes attempted evaluation of sqrt(x) for x < 0.0 or x**(1.0/3.0) for x < 0.0. I felt that the combination of having to know Fortran as well the underlying mathematics was too much for the AI code generators to handle, and terminated my attempt to produce a working program for this problem.

The second problem that I tried has this statement:

"I need a Fortran program to print n, its square root and its cube root when at least one of these roots is a positive or negative integer and n ranges from -30 to +30. Display only those roots that are integers, and display blanks otherwise. "

My experience with Google Gemini was quite similar to what I could have expected by trying the same exercise with an intelligent and willing but inexperienced student/assistant. The following are my requests/inputs to Gemini, followed by the verbal responses from the AI engine. I subjected the program texts that the tool displayed along with these verbal responses to visual inspection or running through a compile+link+run exercise if appropriate. To keep this post from becoming boring, I do not show the program texts.

Me: I need a Fortran program to print n, its square root and its cube root when at least one of these roots is a positive or negative integer and n ranges from -30 to +30. Display only those roots that are integers, and display blanks otherwise.
Gemini: Here’s a Fortran program that prints n, its integer square root, and its integer cube root within the range of -30 to 30: {Program Version A}
Me: You do not seem to know the syntax rules of Fortran. Declarations must appear before executable statements. The intrinsic functions ADJUSTL and TRIM can be applied only to character type arguments. Please correct the code.
Gemini: You’re absolutely right. The previous code contained errors in Fortran syntax. Here’s the corrected version: {Program Version B}
Me: On line 11, you cannot take the square root of a negative argument. Please correct.
Gemini: You’re absolutely correct. The square root of a negative number is not a real number. Here’s the updated code that handles negative values: {Program Version C}
Me: On line 12, you are not permitted to raise a negative number to a non-integer power.
Gemini: You’re absolutely right. Raising a negative number to a non-integer power is not allowed in Fortran. Here’s the corrected code that addresses this issue: {Program Version D}
Me: Check if the CHAR intrinsic function is elemental.
Gemini: No, the CHAR intrinsic function in Fortran is not elemental. It’s a non-elemental function.
Me: In that case, you have to correct the code since it applies CHAR to three-character strings.
Gemini: You’re absolutely correct. Applying CHAR to a multi-character string like a three-character integer representation is not allowed. Here’s the corrected code that addresses the non-elemental nature of CHAR: {Program Version E}
Me: Please display output only when at least one root is an integer.
Gemini: Absolutely! Here’s the corrected program that displays an output line only when at least one root is an integer: {Program Version F}
Me: Congratulations! You produced a working program. You respond cheerfully and are able to correct your responses based on my criticisms, but I wonder if you will be able to remember all that you have learned in this session and apply that knowledge if I were to try the same exercise with you tomorrow.
Gemini: I am still under development, and while I can learn and adapt during a conversation, I cannot retain information specifically from past sessions. Each time you interact with me, it’s like starting fresh. However, the knowledge and capabilities I’m trained on are constantly being improved. So, while I might not remember the specifics of this conversation tomorrow, if you ask me a similar question about Fortran code, I should be able to apply my general knowledge and reasoning abilities to help you again.

Here are some things I can do to be more helpful in future sessions:

I can access and process information from the real world through Google Search (as of June 2024), which can help me understand the context of your questions better.
I can learn from your feedback and improve my responses based on your corrections.
I can guide you to ask clarifying questions or provide additional details that might be helpful.

If you have a similar exercise tomorrow, feel free to ask! I’ll do my best to assist you using my knowledge of Fortran and other relevant information.*

Here is the last version of the program that Gemini generated:

program print_integer_roots

  integer, parameter :: min_value = -30, max_value = 30

  ! Declarations for clarity
  integer :: n, sq_root, cube_root
  character(len=4) :: sq_root_str, cube_root_str

  do n = min_value, max_value

    ! Handle non-negative cases for square root
    if (n >= 0) then
      sq_root = sqrt(real(n))
    else
      sq_root = 0  ! Assign 0 for negative n (no square root)
    end if

    ! Handle all cases for cube root (positive, negative, or zero)
    cube_root = sign(nint(abs(real(n))**(1.0/3.0)), n)

    ! Check for integer square root
    if (n >= 0 .and. sq_root * sq_root == n) then
      write(sq_root_str, '(i4)') sq_root
    else
      sq_root_str = ' '
    end if

    ! Check for integer cube root
    if (cube_root * cube_root * cube_root == n) then
      write(cube_root_str, '(i4)') cube_root
    else
      cube_root_str = ' '
    end if

    ! Print only if at least one root is an integer
    if (sq_root_str /= ' ' .or. cube_root_str /= ' ') then
      write(*, *) n, sq_root_str, cube_root_str
    end if
  end do

end program print_integer_roots

The output from this program:

          -27      -3
           -8      -2
           -1      -1
            0   0   0
            1   1   1
            4   2
            8       2
            9   3
           16   4
           25   5
           27       3

Change the range of n to -3000 to +3000 in the PARAMETER declaration and verify that the program works correctly.

4 Likes

Thanks for telling us about this exercise, which I’ve contemplated but never took the time to try it – interesting!

One comment – cubic equations with some real coefficients can require complex values at intermediate stages of the calculation even for solutions that are real. The wikipedia page has a decent write up.

There was a long thread in this forum on cubic equations a couple of years ago. Here is a short program that assumes that the cubic equation has been scaled to have a leading coefficient of 1. Test it using input coefficients 1, 2, 3 (one real root) and -6,11,-6 (three real roots).

cubic.f90
program cubic
implicit none
complex y2,y3
real b,c,d,Q,R,Dd2,Dd,s,T,alpha,pi,v(3),y1,rt3
read *,b,c,d !solve x^3 + b x^2 + c x + d = 0
Q = (3*c-b*b)/9; R = (9*b*c-27*d-2*b*b*b)/54
Dd2 = Q*Q*Q + R*R   ! discriminant
if (Dd2 < 0) then     ! All three roots are real
   s = -2*sqrt(-Q)
   alpha = acos(-R/(-Q)**1.5)
   pi =  acos(-1.0) !3.14159265
   v  =  (/ s,-s,-s /) * cos((alpha + (/ 0,1,-1 /)*pi)/3) - b/3.0
   print '(A,2x,3F10.5)','Three real roots:',v
else            ! One real root and a complex pair
   Dd = sqrt(Dd2)
   S  = cubrt(R+Dd); T = cubrt(R-Dd); rt3 = sqrt(3.0)
   y1 = S+T
   y2 = cmplx(-y1/2 ,  (S-T)*rt3/2)
   y3 = cmplx(-y1/2 , -(S-T)*rt3/2)
   print '(A,2x,F8.5, 2(", (",F8.5,", ",F8.5,")"))', &
      'One real root and one complex pair:',y1-b/3,y2-b/3,y3-b/3
endif
contains
real function cubrt(x)
   real x
   cubrt = sign(abs(x)**(1.0/3),x)
end function
end program

We can find any number of codes for solving cubic equations in various programming languages, including in languages such as Pascal that do not have a built-in complex type.

1 Like

One reason not to become too dependent on proprietary LLMs is that they can disappear at any time, as they have today.

1 Like

I was inspired to do the same, using Copilot:

  • My first attempt concerned: a Fortran program that reads in an integer and prints the unique prime factors. The result was not too bad, but it fails to filter out the repeated factors. I did not notice that, because I moved on to the next, more complicated program.
  • That second attempt concerned a Fortran program that reads in an integer and prints the Gaussian prime factors. The result looked impressive, but when I studied it more closely, it was actually gibberish: Copilot does understand the concept of Gaussian integers, but the program it produced reads in an integer value AND an imaginary number. It then completely fails to do anything useful with the complex numbers.

What I did notice was that in its answer it included some references, possibly where it got the code or pieces of the code from. I have not checked that.

Some of the free AI tools will take your question/request, and after a few seconds give an answer. At that point, you can take it or leave it, because there is no way for you to protest that the given answer is wrong as to this or that point, or entirely. An example is www.codeconver.ai, which gave this answer for my second question in the initial post (I need a Fortran … blanks otherwise).

PROGRAM print_roots
  IMPLICIT NONE
  INTEGER :: n
  REAL :: sqrt_n, cbrt_n

  DO n = -30, 30
    sqrt_n = SQRT(REAL(n))
    cbrt_n = REAL(n)**(1.0/3.0)

    IF (INT(sqrt_n) == sqrt_n .OR. INT(cbrt_n) == cbrt_n) THEN
      WRITE(*,'(I4,2X,I4,2X,I4)') n, INT(sqrt_n), INT(cbrt_n)
    END IF
  END DO
END PROGRAM print_roots

I tried a thermodynamics question on Gemini:

Me: What is the reduced saturated liquid pressure of a van der Waals fluid at a reduced temperature of 0.7?
Gemini: Absolutely, for a van der Waals fluid at a reduced temperature (Tr) of 0.7, the reduced saturated liquid pressure (Pr_liq) can be calculated using the van der Waals equation of state.

The equation yields:

Pr_liq = 8 * Tr / (3 * (1 - Tr) * (1 + Tr^2))

At a reduced temperature of 0.7, the reduced saturated liquid pressure is:

Pr_liq = 8 * 0.7 / (3 * (1 - 0.7) * (1 + 0.7^2)) = 4.176 (approximately)

Therefore, the reduced saturated liquid pressure of the van der Waals fluid at a reduced temperature of 0.7 is approximately 4.176.

Me: Sorry, that cannot be correct, the reduced saturated liquid pressure can never exceed unity.

Gemini: You’re absolutely right. I apologize for the mistake in my previous response.

The van der Waals equation has limitations in predicting the behavior of real fluids at all conditions, especially near the critical point. In the case of saturated liquid pressure, it can indeed predict unphysical values exceeding unity for reduced pressures.

Real fluids exhibit a maximum reduced saturated pressure at a specific reduced temperature below the critical point. This maximum pressure is always less than 1.

Here are some key points to remember:

  • The van der Waals equation is a good starting point for understanding real fluids qualitatively, but it has limitations for quantitative predictions.
  • Real fluids have a maximum reduced saturated pressure that’s less than 1.

Unfortunately, the van der Waals equation alone cannot provide the exact value of the reduced saturated liquid pressure for a specific reduced temperature. More sophisticated equations of state or experimental data are needed for accurate predictions.

At this point, the AI engine is engaging in erudite bluffing. I wonder if any of the current crop of engines has been taught the virtue of replying “Sorry, I do not know; please ask someone else”, or “The answer is 0.20046 according to a published paper”.

1 Like

I posed this very same question to Copilot and it came up with detailed steps to do the calculations. Then it asked me to specify the critical values, but it also allowed me to do a sample calculation for argon. When I tried that, it presented the detailed steps and ended with: "Let’s proceed with the calculations! :slight_smile: ". Fine, but when I selected its proposal “Can you show me a numerical example for argon?”, I got the same detailed answer, but no numerical value.

From the conversation and the references I think it relies on worked out examples. I guess if these are not available anything can be answered.
Oh, then another thing: as a mainland European I object to the use of non-SI units :slight_smile: . The metric values were supplied, but only as an alternative.

Are you using free version of ChatGPT?

As they are human made and Whatever a human creates will have flaws and will never be perfect.

I have found the new ChatGPT o1-preview to be even better at programming statistical methods than ChatGPT 4o. The o1 model is much slower, often taking 30s-60s to reply, it requires a $20/month subscription, and it only answers 25 queries per week, after which you can use o1-mini or the older 4o. The o1-mini model is still more powerful than 4o, although it is slower like o1. (OTOH, if you ask a human programmer to do something, the response time is measured in hours.)

In finance, stochastic volatility models are used to model the time-varying standard deviation of asset returns. The o1 model was able to simulate and fit such models in Python without much guidance. It “understood” not only Python but the needed statistical theory. Having a good quant/programmer willing to work for you in any programming language 24/7 for $20/month is amazing. Directing the work of the AI programmer and verifying it will become part of the work of human programmers.