Hi!
I've been quite busy thinking about this problem with my very limited knowledge of Python, and I keep on modifying the program to try and reach a solution.
As I said previously in another post,
numpy doesn't seem to work very well with huge amounts of data, so I have been investigating about that and maybe
mpmath would be a solution for that.
mpmath is a free (BSD licensed) Python library for real and complex floating-point arithmetic with arbitrary precision (you can decide with which precision you want your numbers). It has been developed by Fredrik Johansson since 2007, with help from many contributors.
For example, you can compute 50 digits of pi by numerically evaluating the Gaussian integral with mpmath.
To install mpmath (it's free), you can click on the
start sign (I'm showing it for Windows 10, but it might be somewhat different with other operating systems and/or versions), which is at the bottom left corner of the computer (it is the image of a window)
[
attachment=699]
and then type '
cmd' (without the simple quotes), inside the text box (the one with the circle on the left), and press the '
enter' (or '
return') key.
[
attachment=707]
By doing that, the
command prompt, cmd or windows prompt window will pop up (a black window with some writings on it).
You need to go on inside that pop-up window, to the root directory, by typing '
cd\' (without the simple quotes) on that pop-up window, and press the '
enter' (or '
return') key.
[
attachment=703]
The command prompt window will show now something like '
C:\>' (without the simple quotes).
[
attachment=704]
So now you just have to type '
pip install mpmath' (without the simple quotes), and press the '
enter' (or '
return') key.
It is probably going to take some time to load (maybe a couple of minutes). Once it is installed, you can close the command prompt window.
If I use the program
with numpy, it gives the values for 'y' as following:
Output:
These are the values for "y":
[0.000e+00 1.000e-02 2.000e-02 ... 1.797e+01 1.798e+01 1.799e+01]
while if I use
mpmath, the values are shown with more decimal numbers and bigger precision (it produces 1171 lines in my Python 3.7.4 Shell for just the different values of 'y'):
Output:
[mpf('0.0'), mpf('0.01'), mpf('0.02'), mpf('0.029999999999999999'), mpf('0.040000000000000001'),...]
I've been working with many different twists and tweakings to the original code, and
one of the last versions I'm working on is the following one:
from mpmath import mp
import numpy as np
x = np.arange(4,12,.01)
xnumbers = [x]
bigx = len(x)
print("\nThe matrix 'x' has", bigx, "elements.")
y = mp.arange(0,18,.01)
ynumbers = [y]
bigy = len(y)
print("The matrix 'y' has", bigy, "elements.")
mother_of_matrices = bigx*bigy
print("Therefore, the interaction of matrices 'x' and 'y' produces a huge matrix of:", mother_of_matrices, "elements.")
k = 10/(6+x)
print('\n\nThese are the values for "x":\n\n', x)
print('\n\nThese are the values for "y":\n\n', y)
print('\n\nThese are the values for "k":\n\n', k)
print('\n\nThese are the new values for "x" (from the equation):\n')
for x in x:
for y in ynumbers:
if ((1-k) != 0).all():
x = ((y**(1/k)-(y-6)**(1/k))/6)**(k/(1-k))
print(x, sep=',')
for y in ynumbers:
if ((1-k) != 0).all():
x = ((y**(1/k)-(y-6)**(1/k))/6)**(k/(1-k))
mp.plot(x, y)
As you can check, most of the values for 'x', 'y', 'k' and the new values of 'x' obtained from the equation are given with about a precision of 15 decimal positions.
With this version, I don't get any warning or error messages, but still it doesn't plot the pairs (x, y).
I'm going to explain some points on the program. You can notice that for 'y', I've used mpmath (line 9):
y = mp.arange(0,18,.01)
but I had to keep using numpy for 'x' (line 5):
x = np.arange(4,12,.01)
otherwise, with mpmath for 'x', it gave an error on the line 15:
k = 10/(6+x)
:
Error:
Traceback (most recent call last):
File "C:\Users\User1\AppData\Local\Programs\Python\Python37\equations_15.py", line 15, in <module>
k = 10/(6+x)
TypeError: unsupported operand type(s) for +: 'int' and 'list'
That error disappears when using numpy for 'x'.
I've also eliminated the problem when the value of (1-k) was '0', that produced warnings of dividing by '0'. I've avoided that problem with the lines 24 and 29:
if ((1-k) != 0).all():
that checks every element of the matrix and avoids the values that makes
(1-k) = 0
.
The line that still doesn't work is the line 31
mp.plot(x, y)
inside the loop (lines 28-31):
for y in ynumbers:
if ((1-k) != 0).all():
x = ((y**(1/k)-(y-6)**(1/k))/6)**(k/(1-k))
mp.plot(x, y)
The idea for this last loop, was your wish to plot the pairs (x, y). These values for 'x' and 'y' cannot be taken from (line 5):
x = np.arange(4,12,.01)
and (line 9):
y = mp.arange(0,18,.01)
because, as you remember, the list of 'x' values has 800 elements and the list of 'y' values has 1800 elements, so we cannot pair them as the lists have different sizes (that's why if we try, we get the error saying that 'x' and 'y' should have the same size).
Therefore, I thought that for the pairs, we should take just the values of 'y' and then, through the equation, a corresponding value of 'x'. So, if we take the 1800 values of 'y', we should have the 1800 corresponding values of 'x'.
If we move the indentation on line 31
mp.plot(x, y)
and align it to
if
:
for y in ynumbers:
if ((1-k) != 0).all():
x = ((y**(1/k)-(y-6)**(1/k))/6)**(k/(1-k))
mp.plot(x, y)
or even align it to
for
:
for y in ynumbers:
if ((1-k) != 0).all():
x = ((y**(1/k)-(y-6)**(1/k))/6)**(k/(1-k))
mp.plot(x, y)
both produce an error:
Error:
Traceback (most recent call last):
File "C:\Users\User1\AppData\Local\Programs\Python\Python37\equations_15.py", line 31, in <module>
mp.plot(x, y)
File "C:\Users\User1\AppData\Local\Programs\Python\Python37\lib\site-packages\mpmath\visualization.py", line 49, in plot
a, b = xlim
ValueError: too many values to unpack (expected 2)
probably due to too many values to plot at the same time, so I thought that if we print (plot) every single pair as it is calculated, it would be easier to handle by the program:
for y in ynumbers:
if ((1-k) != 0).all():
x = ((y**(1/k)-(y-6)**(1/k))/6)**(k/(1-k))
mp.plot(x, y)
It doesn't produce any error, but it doesn't plot the pairs either.
By the way, we don't need to import matplotlib as before:
import matplotlib.pyplot as plt
and then use something like:
plt.scatter(x,y)
plt.show()
because mpmath already incorporates a built-in plot, so we just need to import mpmath (line 1):
from mpmath import mp
and then call the plot inside mpmath, when we need it, like in line 31:
mp.plot(x,y)
Surely, there must be a neater way to code it, but right now, I would be happy enough by just making it work. I think I only need now to make the plot function work, although I'm not sure how to do it yet...
All the best,