May 6, 2024

The mountain of shit theory

Uriel Fanelli's blog in English

Fediverse

Sleep peacefully.

When I write well about ChatGPT and artificial intelligence, I regularly receive comments according to which the first to lose their jobs will be people like me, because ChatGPT can already program and configure things. And also design. I won't waste time discussing what are the limits of a language model, however large, so, thanks to a casual chat, I decided to give it a try.

So I tried a very simple task: a packet filter configuration of any BSD, which only lets in one port of the IPv6 protocol, and blocks the rest.

I explained the problem to him and then also told him that I meant the OpenBSD Packet Filter.

Look what happened:

If you are familiar with the OpenBSD firewall, you will feel a little uneasy. What he is advising you to do is NOT exactly what you asked him to do. Definitely no.

And so:

Now, one thing is sure: don't use ChatGPT to configure firewalls.


Is the error serious? How serious?

For the uninitiated, I had asked ChatGPT to create a firewall that allowed only a specific port to pass inward (which I intend to defend). In short, this:

What he did was this:

The door is open, but there is no need to feel safe. What I wanted was a system that only let those who passed through a specific door enter, but on the first attempt it opened everything, ALSO allowing you to pass through that door.


When I said there was a problem, he corrected himself. And this means that it can be convenient to avoid typing everything, if you are familiar with Pf, but if you are incompetent using chatGPT and copy-paste is very risky.

The same goes for programmers code:

Now you will say: but the solution is correct. Ni. In the sense that it will approximate pigore (in finite time of course), but I never asked to limit the iterations to 10000. Knowing what to expect, however, I know that he also used an implicit way of declaring variables, and I know that could have been done much better.

With this routine using normal 32-bit floats, and a limit of ten thousand, the result stops like this:

 3.1414926535900345 (10000)

But the problem is: if not 10,000, what is the best number? And what if you use 64-bit numbers?

Let's redo:

package main

import (
"fmt"
"math"
)

func main() {
// n := 10000
// Numero di termini da utilizzare nell'espansione di McLaurin

// Calcola il valore di π utilizzando lo sviluppo di McLaurin dell'arcotangente
var pi float64 = 0.0
var last float64 = 1.0
for i := 0; last-pi != 0; i++ {
last = pi
sign := math.Pow(-1, float64(i))
term := sign / (2*float64(i) + 1)
pi += 4 * term
fmt.Printf("Numero di iterazioni %d , valore %1.30fn", i, pi)

}

}

Is this code better? Well, if we want to keep the arctangent McLaurin series paradigm, yes. In fact, it ends like this:

 Number of iterations 27830 , value 3.141628584745683294698892495944 
Number of iterations 27831 , value 3.141556723724897359772967320168 
Number of iterations 27832 , value 3.141628582163772609447960348916 
Number of iterations 27833 , value 3.141556726306621971644972290960 
Number of iterations 27834 , value 3.141628579582233182776462854235 
Number of iterations 27835 , value 3.141556728887975769026752459467 
Number of iterations 27836 , value 3.141628577001064570595190161839

Why does it end like this? Because a decreasing series ends up converging but does so only in R, while the computer does not use R, but only a discrete set. And therefore it has a machine epsilon.

Second, the number of iterations it goes through before it can't distinguish two successive values ​​(after that point going on would be useless) is 27836, which makes the previous limit of 10,000 iterations, which I never asked, arbitrary.

And if you look at the numbers with a mathematical eye, you notice that the machine error produces chaos, and this chaos has two attractors: { 3.14155672 , 3.1416285}. Which means that the algorithm stopped "almost by chance". The result, that is, orbits around those two points, because truncation produces chaos.


Now, it is true that not even the average programmer knows that he can generate chaos and attractors even by mistake, writing apparently correct code. The thing does not change if we use the sum of the remainders, because in this case the problem is the truncation due to the machine epsilon (where machine is the golang number model) . But now we can estimate the error:

 package main

import (
"fmt"
"math"
)

func main() {
// Number of terms to use in the McLaurin expansion
// n := 10000

// Calculate the value of π using the McLaurin expansion of the arctangent and the remainders of the series
pi := 0.0
prevPi := 0.1
remainders := 0.0
for i := 0; pi-prevPi != 0; i++ {
sign := math.Pow(-1, float64(i))
term := sign / (2*float64(i) + 1)
prevPi = pi
pi += 4 * term
remainder += math.Abs(pi - prevPi - 4*term)
fmt.Printf("Number of iterations %d , value %1.30f , error: %en", i, pi, remainder)
}

}

And we will also get the precision:

 Number of iterations 24311 , value 3.141551521638504151923143581371 , error: 2.699995e-12 
Number of iterations 24312 , value 3.141633783849301142510057616164 , error: 2.700070e-12 
Number of iterations 24313 , value 3.141551525021900825862530837185 , error: 2.700169e-12 
Number of iterations 24314 , value 3.141633780466182912505246349610 , error: 2.700301e-12 
Number of iterations 24315 , value 3.141551528404740611932766114478 , error: 2.700311e-12 
Number of iterations 24316 , value 3.141633777083621126280377211515 , error: 2.700392e-12 
Number of iterations 24317 , value 3.141551531787023954223059263313 , error: 2.700464e-12 
Number of iterations 24318 , value 3.141633773701615783835450201877 , error: 2.700521e-12 
Number of iterations 24319 , value 3.141551535168751296822620133753 , error: 2.700608e-12 
Number of iterations 24320 , value 3.141633770320166885170465320698 , error: 2.700724e-12 
Number of iterations 24321 , value 3.141551538549922639731448725797 , error: 2.700912e-12 
Number of iterations 24322 , value 3.141633766939273986196212717914 , error: 2.700990e-12

As you can see, using the sum of the remainders the value arrives slightly earlier, the rest of the series would be around 10 to the minus twelve, but we still have some chaotic effects.

Actually I hope you will never use this method because it sucks for other reasons (under truncation conditions the remainder will reach a minimum and then keep growing albeit slowly), but the problem is that:

  1. he added a requirement that was never requested (he "dreamed", as AI experts say), that is 10,000 iterations.
  2. he used a technique that generates a chaotic effect with two attractors.

It could have been done better? Yes, you could use a producer. We could also discuss his concept of the Mc Lauren series, actually.

But the point is, if you know what you're doing, you know how to handle the mistakes it makes. If you don't know, a code that "works" you copy and paste it, and if what you were doing was making yourself lazy at home, well, you got a free requirement (which you might not notice) and some side effects which in numerical calculation are quite unwelcome.

It's true that the average programmer doesn't know how to recognize the two attractors, like I did, because they've never done HPC. So it doesn't even recognize that it has created a chaos effect, nor does it know that it is the truncation that causes it.

But the point is, if you copy and paste code with unknown side effects and requirements that fell out of the sky, you could write MUCH worse things than this.


And that is why, dear gentlemen, that:

  1. I don't think ChatGPT will take my job away, nor will it take it away from good programmers.
  2. ChatGPT, being a language model, CANNOT avoid these errors.
  3. Thus, it cannot even reprogram itself or "improve" itself. He can't do.

There are many reasons why a natural language model will be uncomfortable with programming or very formal logic.

But the point is very simple: you can sleep soundly.

Others will lose their jobs.


Last note:

As you can see, he knows only one series for calculating pi that he identifies with both McLaurin and Taylor. The trouble comes if I ask him this question:

The code is this:

 package main

import (
"fmt"
)

func main() {
// Number of terms to use in the series
n := 10000

// Calculate the value of π using the approximation series
pi := 0.0
for k := 0; k < n; k++ {
pi += 1.0/(float64(k)*8.0+1.0) - 1.0/(float64(k)*8.0+4.0) - 1.0/(float64(k)*8.0+5.0) - 1.0/(float64(k)* 8.0+6.0)
}
pi *= 4.0

// Print the calculated π value
fmt.Println("Calculated π value:", pi)
}

Which at first intrigued me because I didn't know her, and which would also be interesting.

If only that code calculated pi, I mean:

 Calculated π value: -2.6657193990759604

Now excuse me, I'm going to sleep peacefully.

Leave a Reply

Your email address will not be published. Required fields are marked *