OK and sorry for being such a newbie with the G’MIC syntax
No apology is needed. It took me years to understand gmic syntax, and I believe there is still lessons to go.
The file is now runnable without error, with gmic schrodinger_well.gmic rep_hamiltonian
Now I need to store the linear gradient pixels into a variable (tried something already, but not working rereadable yet after assignment) and read the abs() value from two of its pixels… #increment = np.absolute(x_intervals[0] - x_intervals[1])
Sorry that I haven’t gotten back to this - The author updated : https://github.com/weightan/SchrodingerWellPython/blob/main/Hamiltonian_solver.py
There are multiple ways of storing linear gradient pixels into a variable.
Method #1 (outside of fill math interpreter)
length,1,1,1,expr
v={crop(#-1)}
or
v={[expr()]}
Method #2 (math interpreter)
f "begin(v=expr('formula',w,h,d,s);
);"
or
eval "begin(v=expr('formula',w,h,d,s);
);"
or
w1,h1,d1,s1,"begin(v=expr('formula',w,h,d,s);
);"
Hello,
last week I sat down a few minutes with David, he taught me some G’MIC syntax and we went in that same direction which you are pointing of translating further lines, using the vector type namely. I will adapt more lines of code soon in the aforementioned Github fork, where you can contribute too.
Here are our notes:
toto :
# 400,400,1,3
eval "
# const N = "$1";
# const No_points = N*N;
# x_intervals = expr('lerp(0,1,x/(w-1))',200);
# increment = x_intervals[1]^2;
# incrementValue = -1/increment;
# zeroV = 4/increment;
# diagmM = vector(#No_points - N + 1);
# for (i = 0, i<size(diagmM), ++i, diagmM[i] = incrementValue*position_mesh[i]);
# diagsK = [ -N, -1, 0, 1, N ];
# diagsV = [ diagmN, diagm1, diag0, diagp1, diagpN ];
M = vector(#100,30);
store(M,'M',10,10);
"
You are obviously much more skilled than me in G’MIC… What blows my mind is that people skilled in the G’MIC syntax do not necessarily understand Python/Numpy syntax easily, while the latter is like human language to me.
(no offense intended, I am just astonished by different ways of understanding code in the universe)
No offense at all. I use the g’mic syntax since I try to make order of images, and localized vector in context of images, and how they are all processed. I don’t use nm
/name
unlike other gmic developer for that reason. Not to mention that it is the perfect
language for generic raster image processing. Other languages like p5js and other are more suitable for vector processing.
I think you’re going to complete this sooner than I could since I literally do not understand python anywhere near proficient level. On position_mesh = np.matrix.flatten( matrixWell2D )
, I seem to be getting the impression that it is the cropped vector of a image. But, I have a feeling it’s more than just that.
Here’s the fixed code:
rep_hamiltonian:
if s>1 to_gray. fi
eval "begin(
position_mesh=crop(#-1);
const N=$1;
const No_points=sqr(N);
const Np_N=No_points-N;
const Np1=No_points-1;
diagmN=vectorNp_N(0);
diagm1=vectorNp1(0);
);
x_intervals = expr('lerp(0,1,x/(w-1))',200);
increment = x_intervals[1]^2;
incrementValue = -1/increment;
zeroV = 4/increment;
diag0=vectorNo_points(zeroV);
for(p=0,p<Np_N,p++,
diagmN[p]=incrementValue*position_mesh[p];
);
for(p=0,p<Np1,p++,
diagm1[p]=incrementValue*position_mesh[p];
);
diagpN=diagmN;
diagp1=diagm1;
diagsK = [ -N, -1, 0, 1, N ];
diagsV = [ diagmN, diagm1, diag0, diagp1, diagpN ];
M = vector(#100,30);
store(M,'M',10,10);"
Being well documented and having plenty of snippets across the web, Python is fairly easy to learn. The reason I lost it was I didn’t take the leap to py3 and stopped experimenting with opencv.
G’MIC, on the other hand, is super handy because it has builtin convenience features such as dimension looping, element wise operations, boundary conditions, interpolation and data management.
@afre The only downside the lack of vector support. If g’mic had vector image support, and be able to convert from vector to raster, some of my dream filters can be made and rapid version too.
Could you be more specific? I mean, the wish list can be endless.
I find certain types of indexing such as in Octave / Matlab is useful. I would also like more flexible ways to retrieve stats such as “the median of the red (or even chroma; e.g., Cz, illum=E) channel of the fifth image”. And more control of the sequence (vector) in which fill
processes pixels.
I was thinking as vector as in vector image, svg image, inkscape, illustrator. Being able to manipulate vector images, and to convert from vector image to raster image. That’s about the only wishlist I have for gmic.
I once asked about graph processing, (which is loosely? related but more sophisticated than just vectors). I don’t know. Seems more like something in the realm of an extension or community project. Perhaps, it is the reverse of Fun with random curves but that doesn’t look simple either. I do see the Fourier series drawings having the application of closing cartoon curves and colouring them, as shown in previous posts, which is a problem not completely solved in the current implementation.
That’s in fact what object3d
can be used for. A 3d object is a set of vector primitives. The thing that is currently missing is the import/export in various vector file formats anyway, but as long as you can generate the shapes with code, it’s very convenient to use.
It is not just ‘proficiency at Python’ which is at issue, it is proficiency with NumPy, which introduces its own paradigm. np.matrix.flatten()
is the NumPy workalike of G’MIC’s -unroll. Both take a 3x3 and rearrange it as a 1x9, no more no less. After spending a great deal of time with Python, and a great deal of time with NumPy, the equivalency to -unroll
is ‘instinctively obvious,’ to me, probably because I have also spent a great deal of time writing G’MIC tutorials, so I can navigate the three paradigms - if not with ease, then without stumbling too much. I share @myselfhimself intrigue on why perfectly intelligent and capable people are so proficient with one paradigm while finding others opaque - especially with G’MIC, where the order of magnitude of the proficient can be measured in the tens, while the proficient in Python/NumPy can be measured in the tens of thousands, modestly, I think. That bodes ill for G’MIC, because working examples are few and far between. Consequently, there is little drawing power bringing new people - and new points of view - to G’MIC. I’m hijacking this thread, now, for which I apologize, and will take these notions over to Tutorial Fragments, where it is better situated, I think.
Another alternative solution (Faster code though harder to understand):
rep_hamiltonian:
if s>1 to_gray. fi
n={$1}
npts={sqr($n)}
npts_n={$npts-$n}
npts_1={$npts-1}
#x_intervals image#
200,1,1,1,":begin(const ww=w-1);lerp(0,1,x/ww)"
increment={sqr(i(#-1,1))}
incrementValue={-1/$increment}
zeroV={4/$increment}
diag0={[vector(#$npts,$zeroV)]}
rm.
repeat $! l[$>]
$npts_n,1,1,1,"begin(
const inc_v="$incrementValue";
);
inc_v*i(#-1,x);"
$npts_1,1,1,1,"begin(
const inc_v="$incrementValue";
);
inc_v*i(#-2,x);"
diagmN=[{crop(#-2)}]
diagm1=[{crop(#-1)}]
diagpN=$diagmN
diagp1=$diagm1
diagsK=[-$n,-1,0,1,$n]
diagsV=[{[$diagmN,$diagm1,$diag0,$diagp1,$diagpN]}]
rm[-2,-1]
endl done
I apologize for not having made progress… I am busy with a paper origami castle and getting a career coaching (for me) week ready.
Is the conversion to G’MIC with that last piece of code which you pasted satisfactory to you?
Is the following pseudo-code passage included in your piece of code, though in a different somewhat optimized form? It seemed that me that the hamiltonian function would start with some input shape, which can a circle, or something else…
$1,$1,1,1 fill_color $3 circle 50%,50%,$1/4,1,$2
Your comments are super welcome.
One nice thing nowadays is that most Numpy API-related questions are documented through beginner StackOverflow questions+answers, and also with nice API documentations pages.
It seems that G’MIC is for tinkerers coming from the ugly-non-production-ready-scripts world (matlab, scilab…)… While numpy is OK for those people, with either that same science-tinkerer background, or a classic programming background (Java, C etc…). I think that I am still bad at the G’MIC language because I have not read the syntax documentation yet. Most new popular language that is come out have a C-like syntax, hence my laziness.
David made me realize last week that the G’MIC language is structured mostly for images management on the top level, and then has a GL pixel-shader-like domain-specific-language (DSL) that needs to be written in quotes for the eval and fill commands.
Global variables also need to be prefixed with an underscore… while in Python, this is just a cultural Python programmer tip for signaling a private attribute or member.
It seems like understanding G’MIC is just 4 web pages of reading away… so I will catch it up soon hopefully!
Don’t want to clutter your & @Reptorian 's thread with tutorial rants. That’s all. Could use your insights in a potential Cookbook article. Visit Tutorial Fragments if/when you have a moment. Thanks!
It may need some work. The important thing to focus on is getting it to work.
The steps to convert from one language to another:
- Get it to work no matter the speed.
- Find optimization, and see to that you can fix bugs
The two things that bothers me pertaining to the python code:
Hamiltonian = diags(diagsV, diagsK, format = 'dia')
e_values, e_vec = eigs(Hamiltonian, k = Elevels )
I believe after those are translated, the 2d version is solved, however there could be more to do.
That is why I didn’t add a built-in input.
@Reptorian
diags
makes a square matrix with only a few upper and lower diagonals populated (dark blue) the center diagonal (cyan) and the outer cells (white) are zero-ed out. Mostly non-zero data in the dark blue. diag
assembles these from the various diagmNN
… diagpNN
1 x (big number!) linear arrays computed upstream in the functiongeneral_potential_3d()
. diagsK helps diag
layout the data into the matrix. Here’s the schematic of that matrix:
This square matrix is the one called Hamiltonian.
eigs solves for the eigenvalues and eigenvectors of this square matrix. That can be a big, long computation - maybe impossible to do. For that reason, the second parameter, k
puts a limit on the number of eigenvalue, eigenvector pairs that come back. The limit in the test case puts k = Elevels = 50, N = 70, and N**3 = No_points ‘number of points’ = 343,000. The matrix is hefty. G’MIC’s math expression has an eig(A)
which appears to be the work alike of eigs
. G’MIC’s version doesn’t have a limit parameter. Maybe, let’s be hopeful, that it doesn’t need it.
Got some free time this evening (EDT) to single-step through the Python script via IPython
(debug mode). Will post observations here. If there is anything you want me to pay attention to, let me know. Cheers.