User talk:Sam Derbyshire/Archive 1

(Redirected from User talk:Sam Derbyshire/Archive1)
Latest comment: 16 years ago by Somody in topic Graphs

Lambert W function, graphs, ...

Hi Sam

Love the Lambert W function pictures! Do you mind if I clarify that the surfaces are the principal branch?

Best wishes

Robinh 19:44, 25 November 2006 (UTC)

Hi,
Well I thought it was clear it is the principal branch (as I wrote W0) but of course, go on and add that, I don't mind (why should I ? :D)
Thanks,
(I'm thinking about doing the same for logarithm and exponential, should I ?)
--Xedi 19:53, 25 November 2006 (UTC)
Hi again Xedi . It did say  . I missed that! Check out Weierstrass elliptic function for another visualization scheme for complex functions.
Best wishes, Robinh 21:35, 25 November 2006 (UTC)

Nice graphs.

Your graphs of those functions are truly awesome - I'm just having a crack at something like it with MuPADs free trial, but I can't get the projected contour lines and the contours lines on the plot itself to work properly. Perhaps it's because I'm not used to the Maple-esque environment - I generally use Mathematica for most "serious" work, but since the object here is to make it look as good as possible as well, I'm branching out. However, MuPAD's fighting back with spirit!

For a start, I'd quite like to redo some quantum wavefunction graphs on Commons, and I'd like to see if I could make them look half as good as yours.

Also, how do you get the images to be all oriented the same way? I can never get them back the way they were after making them bigger or whatever...

Sorry to be such a pain, but I would love to know how to draw graphs like that.

inductiveload - on Commons - that's where I'm most active.Inductiveload 20:18, 13 February 2007 (UTC)

Sorry I had written a reply in the edit box thing and I had left it while i tried to plot sometihng to see it it was worth mentioning, but my PC crashed (I used all my RAM on Mathematica and muPad combined....I was even watching the CPU usage at the time). I thought I had saved my post but clearly not. I was quite busy picking up the pieces! It's time like that I wish I used Mozilla which doesn't lose form data like that...
I've spent several hours now wresling with MuPAD, and I'm begiinging to get results! How do you stop the contour lines (the projected ones at the bottom) from getting all chopped up? Inceasing the SubMesh seems to make the gaps smaller (so they get lost in the resolution), but there are more of them if you zoom in. The only thing I can think of it plottong each one ith it's equation, but I'll be damned if i'm going to do that!
I've figuredo ut the camera position control, so all my graphs are from the same angle which is good...
Also the colouring's a little tricky - I have a sort of hacked-together function doing it ATM (complete with trial-and-error values), which works OK but goes a bit monochomatically pink in the middle).
colourfunc := zip(RGB::Red, RGB::CornflowerBlue,
                 (a, b) -> (f(x,y)+6)/(12)*a
                          -(f(x,y)-6)/(20)*b):

I haven't had a chance to see if it looks better in orange and yellow or some other combo.

I'll polish up one of my plots and post it on Commons in a bit. Then I might have a go at a Taylor series or something - that seems to lend itself well to this.
Thanks again,
Inductiveload 19:00, 16 February 2007 (UTC)
For the contour lines at the bottom, If you're talking about what I think, just put their opacity down (quite funnily, at opacity=99% (or whatever except 100%), the choppiness disappears)).
For the colouring, actually, I mostly use the simple dichromatic way, not a custom function for the colour. But, after seeing for example the klein surface in your gallery, I really see the benefits of not simply doing a z-based colouring. I've tried to come up with some colouring functions, but well, they aren't great. Actually I spent a lot of time trying to get nice "density" plots (like your black and white plots of wavefunctions) in colours, but had a hard time antialiasing the borders (to be like these http://mathworld.wolfram.com/images/eps-gif/ParabolicCylinderDContours_851.gif), I finally ended up doing a geometric mean that smoothes the borders...
I'll try to find a better way for colouring graphics, especially a way to get something resembling the Mathematica colouring I quite like on some plots (like your Klein surface plot),.
About Taylor series, maybe you've noticed the few plots I did on Wikipedia, I personnally quite like the animation of the approximation of cos(x) over the complex numbers with Taylor Series. I've also used the equation you gave for the Fourier Series for a periodic x^3 function to do an animation.
One thing that I really like with MuPad, is the quality of the help inside it : I've learnt about everything just looking up in the help.
If you would like more advice, please say so, I'm happy to help. --Xedi 19:47, 16 February 2007 (UTC)
The Mathematica plots are coloured by having lots of differnet coloured lights shining on them from differnet angles, I think. I'll check for you. I have to catch a train now, I'll post back tomorrow proabably with details.
The tip about the opacity was right on - thanks a lot. I can't find a way to put subscripts or special characters (like ψ) in the axes titles, though - do you know how to do that? I'd be interested to see the Fourier series animation - is it a complex one or a real one? I can see how that would shape up nicely - I might try it on the train.
I agree, the help uis good on MuPad, it's just learnig a whole new package with its quirks (eg. sin(x), not Sin[x]) take time. if you ever use Mathematica, check out this site for some really good antialising code. Be warned though - it will kill your computer for the time it's working!
Inductiveload 20:35, 16 February 2007 (UTC)

Hi there - I've found out about Mathematica's lighting:

The default lighting used by Mathematica involves three point light sources, and no ambient component. The light sources are colored respectively red, green and blue, and are placed at a angles on the right‐hand side of the object. Objects are by default coloured matte white.

It shouldn't be too hard to replicate this in MuPad. I haven't tried yet, though. I have also uploaded a Wavefunction plot here

Inductiveload] 16:54, 18 February 2007 (UTC)

Thanks !
But I don't seem to be able to correctly replicate that lighting as MuPad lighting gives reflections... I tried to change the lighting to flat but it only gets worse...
Oh well, don't hesitate to say if you find out how to do !
Thanks again, --Xedi 16:59, 18 February 2007 (UTC)
MuPAD seems to have quite a shiny surface -Mathematica uses a purely matte (reflects light in all direcetions, like a sheet of plain paper) white surface. I'm not sure how to change this in MuPAD. Perhaps you old use DistantLight to simulate it (it's more like sunlight). The help page on this shows some exmaples.
129.31.77.98 22:47, 18 February 2007 (UTC)
Yes, sadly I can't see any options to make the surface matte. Oh well, I guess a color function could be made to give the same results, but I suppose it will need a lot of fine tuning...
--Xedi 23:55, 18 February 2007 (UTC)

Possible colour function?

Hi again. I think i may have found a passable solution to the MuPAD colouring. I was looking through the help files and i found the following code that generates quite a nice colouring:

hsv := (u, v, r, phi, theta) ->
    RGB::fromHSV([180/PI*(phi+(theta+2)^3/PI^2),
                  3/4+sin(u)/4, 1]):
plot(plot::Spherical([1, u, v], u = 0..2*PI, v = 0..PI,
                     FillColorFunction = hsv))

This does a sphere, and there is some smaple code for a height-related scheme:

hsv := (x, y, z) -> RGB::fromHSV([150*z, 1, 1]):
plot(plot::Function3d(sin(x*y)*(x-y), x = -3..3, y = -3..3,
                      Submesh = [2, 2], FillColorFunction = hsv))

Not quite the same as the Mathematica plots, but is reasonably close. Tweaking some parameters might help. Here is a fuction I wrote for an exponetial density plot. It is based on the arctan function, so when values get very big, its doesnt change much, preventing it wrapping round and round when the graph gets steep. You should be able to drop it into any old graph as a colour function. You might need to play with the parameters to get the optimum filling of the spectrum.

hsv := (x, y, z) -> RGB::fromHSV([100+100*arctan(z), 1, 1]):

You can see this in action here.

Hope something here helps! Inductiveload 02:03, 20 April 2007 (UTC)

More...

First off, i had a go at making a Mathematica syle lighting scheme using point light sources. This works kind of OK - it's on the right lines, but it's still not anywhere near what you want (you have to turn the sphere around):

dist  := 20:
intent:= 1:

                 
sphere := plot::Sphere(0.5, [0,0,0]) :

l1 := plot::PointLight([dist,0,dist], 
                          intent,
                          LightColor = RGB::Red):
                          
l2 := plot::PointLight([0,dist,dist], 
                          intent,
                          LightColor = RGB::Blue):
                          
l3 := plot::PointLight([dist,dist,dist], 
                          intent,
                          LightColor = RGB::Green):
                          
ambientlight := plot::AmbientLight(0.0):

plot(sphere,
     l1, l2, l3,
     Axes = Frame,
     FillColor = RGB::White, 
     FillColorType = Flat, 
     Lighting = Explicit):

Now, about those Mathworld plots. They were eported to a vector format (eps - it's in the url), which wean they will have been antialised by another piece of software, which give them that nice clean edge. I've tried the antialiasing command (AntiAliased = TRUE) for density plots, but it doesn't seem to do anything at all. The thing is, a density plot is the wrong way to go about this as it is inherently pixelated - what you really want is a contour plot, made up of lines done in MuPAD's nice antialised style, filled in. This is how this was done - Mathematica conveniently has a ContourPlot command. I'm still trying to work out how to do this in MuPAD... This may be heresy, but I'm seriously considering trying to just fill in the colours in Photoshop...

Your orthogonal plot looks very pretty and I'm torn betwen it and the density plots, but I don't really like the big missing chunks and I'm not sure that it conveys much more information about the curve that the 3D plots as it sufferes the same "can't deal with big numbers" problem. Also it struggles to display a plot like Image:Exponential Function (Real Part at Infinity).png without making a hash of the large number of holes around the centre. In fact, to be fair, the density plot also produced a less than optimum result too... However, the one thing that I really do like about it is the z-contours. Have you any idea how to superimpose z-contours onto a density plot, and perhaps the grid lines (but not the mesh lines - there are hundreds of those)

BTW, a density plot of mesh 1600*1600 take me about 5 minutes ish to do, so I leave it running while i do something else, like writing this.

I still need to do some work on the density plot shading - its a bit misleading as the flat green plane doesn't seem to be quite at zero, so the colour bands don't line up and equal absolute values (if that makes sense). (This is partly why I want to superimpose contours on it.)

I couldn't get the conformal plot code to work. I'm not quite sure how a conformal plot works, so i couldn't fix it (easily).

Thanks for your comments on the Klein bottle construction! Do you know of any similar things I could do - I quite enjoyed it and would love to do some more. I don't know much about topology, so I don't know what else is out there. anything easily geometrical constructed could be made.

One more thing: how do you comment in MuPAD? You mentioned it, but I couldn't find anything in the help.

Cheers, inductiveload 23:03, 20 April 2007 (UTC)

Colour Functions

Hi again. I've been thinking about the colurs too, but I haven't seen that graph before, that's very good. It explains a hell of a lot, I thought that the HSV spectrum was smoother than that, I have to admit. The colours need to drop away more slowly from the plateaus. Perhaps a piecewise straight line/sinusiod might be better. Or maybe a scheme something like 3-phase power lines, with three sinusoides, 120 degs out of phase each. I'll get on trying to write a function that maps an angle onto the RGB. I'll get back to you on that.

It seems that some of the density plots aren't too bad, like Image:Exponential_Function_(Abs_Imag_Part_at_Infinity)_Density.png, whcih is a density plot of Image:Exponential_Function_(Abs_Imag_Part_at_Infinity).png. Since this runs form 0 upwards, not up and down, the scheme is different. This runs form green=0 through to yellow=big.

I like your conformal plot - that's very pretty. I don't actually know anythng about conformal plots, so I'll leave that to you until I learn, at which point I'll come back to it .

What abotu the LAB colours? Is that cyclic like HSV? I don't know, but I'll check.

Sorry i haven't got many answers. I'll see what happens. Cheers,

Inductiveload 20:24, 23 April 2007 (UTC)~

Result!

I've used you code to hack up a working colour function. You can see it here in non-linear form (arctan is back!) on a density plot (the resolution is set to 100X100, so it shouldnt take to long to render, and you can change it if you want). I can upload a high res version if it would take you too long, but this give the idea.

  f := Im(exp(1/(x+I*y))):

  ylimit := 1:
  xlimit := 1:
  mesh := 100:     //resolution of density plot
   
a:=1:              //change this to adjust the colour band drop-of rate
fmin := -1:        //minimum value of colur function (i.e the one with arctan in it)
fmax :=  1:        //maximum value of colour function
range:=zmax-zmin:  //for brevity
  
colour := proc(c)
 begin
    if   c <  fmin then
       return ([1, abs(sin((c-fmin)*(PI/2)/(range/6))^a), 0])  //this term may not be needed, but it means we can deal with slightly under-limit values
    elif c <= fmin + 1*range/6  then 
       return ([1, abs(sin((c-fmin)*(PI/2)/(range/6))^a), 0])
    elif c <= fmin + 2*range/6 then
       return ([abs(sin((c-fmin)*(PI/2)/(range/6))^a), 1, 0])
    elif c <= fmin + 3*range/6 then
       return ([0, 1, abs(-sin((c-fmin)*(PI/2)/(range/6))^a)]) 
    elif c <= fmin + 4*range/6 then
       return ([0, abs(-sin((c-fmin)*(PI/2)/(range/6))^a), 1])  
    elif c <= fmin + 5*range/6 then
       return ([abs(sin((c-fmin)*(PI/2)/(range/6))^a), 0, 1])
    elif c <= fmin + 6*range/6 then
       return ([1, 0, abs(sin((c-fmin)*(PI/2)/(range/6))^a)])
    else 
       return ([1, 0,abs(sin((c-fmin)*(PI/2)/(range/6))^a)])
  end_if
end_proc:

  colfunc := (x,y,z) -> colour(arctan(z)/(0.5*PI*1.2)): //the factor of 1.2 prevents the spectrum from wrapping around and merging.

  
  cplot := plot::Density(f, 
                         x = -xlimit..xlimit, 
                         y = -ylimit..ylimit, 
                         AntiAliased = TRUE,
                         Mesh = [mesh, mesh],
                         AxesTitleFont = ["Courier New", Bold, 14],
                         TicksLabelFont = ["Arial", 10],
                         FillColorFunction = colfunc,
                         YTicksDistance = 0.5,
                         XTicksDistance = 0.5):
  
  plot(cplot,
       Axes = Frame,
       Width = 8.5*unit::inch, 
       Height = 7*unit::inch):

The only problem with this function is that red is on the end, so unless you allow it to wrap around, you can never have red on your plot (without some sort of fuction hack).

I'm ging to shuffle the order of the function so that it has green at the centre, and magenta at the ends. If you omit the ends, then you will get red and blue ends, which I think looks best. I might also try a version with green at the bottom, going up, for absolute value plots like Image:Exponential_Function_(Abs_Imag_Part_at_Infinity)_Density.png. It seems that having green at zero works quite well.

Heres's the code for a 3D surface with the same kind of scheme, but linear and wrapping around to red at the extremes:

  q := Im(exp(x+I*y)):

  conts := 21:
  projectionlevel:=-10:
  ylimit := 2*PI:
  xlimit := 3:
  submeshlevel := 6:

a:=1:
zmin := -10:
zmax := 10:
range:=zmax-zmin:

colour := proc(c)
 begin
    if   c <= zmin then
       return ([1, abs(sin((c-zmin)*(PI/2)/(range/6))^a), 0])
    elif c <= zmin + 1*range/6  then 
       return ([1, abs(sin((c-zmin)*(PI/2)/(range/6))^a), 0])
    elif c <= zmin + 2*range/6 then
       return ([abs(sin((c-zmin)*(PI/2)/(range/6))^a), 1, 0])
    elif c <= zmin + 3*range/6 then
       return ([0, 1, abs(-sin((c-zmin)*(PI/2)/(range/6))^a)]) //([abs(-sin((c-zmin)*(PI/2)/(range/6))^a),0,1])
    elif c <= zmin + 4*range/6 then
       return ([0, abs(-sin((c-zmin)*(PI/2)/(range/6))^a), 1])   //([0, abs(-sin((c-zmin)*(PI/2)/(range/6))^a), 1])
    elif c <= zmin + 5*range/6 then
       return ([abs(sin((c-zmin)*(PI/2)/(range/6))^a), 0, 1])
    elif c <= zmin + 6*range/6 then
       return ([1, 0, abs(sin((c-zmin)*(PI/2)/(range/6))^a)])
    else 
       return ([1, 0,abs(sin((c-zmin)*(PI/2)/(range/6))^a)])
  end_if
end_proc:

colfunc := (x,y,z) -> colour(z):

funcplot := plot::Function3d(q(x,y),
                             x = -xlimit..xlimit,
                             y = -ylimit..ylimit,
                             Mesh = [23, 23],
                             Submesh = [submeshlevel,submeshlevel],
                             LineColor = RGB::Black.[0.4],
                             LineWidth = 0.15,
                             FillColorFunction = colfunc,
                             AxesTitleFont = ["Courier New", Bold, 14],
                             ViewingBoxZRange = -10..10,
                             YTicksNumber = None,
                             YTicksAt = [-3*PI/2 = "-3 PI/2", -PI = "-PI", -PI/2 = "-PI/2", -2*PI = "-2 PI",
                                         0 = "0", 
                                         PI/2 = "PI/2", PI = "PI",  3*PI/2 = "3 PI/2", 2*PI = "2 PI"]
                            ):

contours := plot::modify(funcplot,
                         ZContours = [Automatic, conts],
                         LineWidth = 0.2,
                         LineColor = RGB::Gray90.[0.5],
                         XLinesVisible = FALSE,
                         YLinesVisible = FALSE,
                         Filled = FALSE
                        ):
                        
projcontours := plot::Transform3d([0, 0, projectionlevel],
                                  [1, 0, 0, 0, 1, 0, 0, 0, 0], 
                                   plot::modify(funcplot, ZContours = [Automatic, conts],
                                                LineWidth = 0.2,
                                                LineColorType = Dichromatic,
                                                LineColor = RGB::DarkGreen.[0.99],
                                                LineColor2 = RGB::Yellow.[0.99],
                                                XLinesVisible = FALSE,
                                                YLinesVisible = FALSE,
                                                Filled = FALSE
                                               )
                                  ):
                             
camera := plot::Camera([25, 80, 120],
                       [0.5, 1, 0],
                       0.15
                      ):
                             
ploteverything := plot::Canvas(funcplot, contours, projcontours,
                               Width = 8.5*unit::inch, 
                               Height = 7*unit::inch,
                               camera
                              ): 
                       
plot(ploteverything);

This needs quite a high submesh as it seems that colour functions are computed in little squares, and only LOOK smooth, but actually aren't. You can see this as a ragged if you change one of the function bands (try removing the zmin form a term). It seems to take a bit longer to render than normal, but it's not too bad.

One more thing - i only have an LCD monitor on a laptop, so I cant quite tell when the bands are equal width, as the primary colour bands expand when i tilt the monitor back (or move my head a few inches), and shrink when it tilk it forwards. Do you have a CRT? If so, (or an LCD that doesnt do this) then could you tell me which value of "a" works best? 1 - 1.2 seems good but it's hard to tell. I'm using 1, as you can see.

Thanks for that code, you did a great job. You must have worked fast to get it done so soon.

Cheers,

Inductiveload 16:54, 24 April 2007 (UTC)

Examples of new function

Here you go - a 1000x1000 plot of the imaginary part near infinity, using the blue-red, green centred colours. This image. This imageshack thing's good, I got that from you... cheers.

Heres' the revised colourfuction:

  f := Im(exp(1/(x+I*y))):

  ylimit := 1:
  xlimit := 1:
  mesh := 1000:     //resolution of density plot
   
a:=1:              //change this to adjust the colour band drop-of rate
fmin := -1:        //minimum value of colur function (i.e the one with arctan in it)
fmax :=  1:        //maximum value of colour function
range:=zmax-zmin:  //for brevity
  
colour := proc(c)
 begin
    if   c <  fmin then
       return ([1, 0,abs(cos((c-fmin)*(PI/2)/(range/6))^a)])  //([1, abs(sin((c-fmin)*(PI/2)/(range/6))^a), 0])
    elif c <= fmin + 1*range/6  then 
       return ([1, 0,abs(-cos((c-fmin)*(PI/2)/(range/6))^a)])   //([1, abs(sin((c-fmin)*(PI/2)/(range/6))^a), 0])
    elif c <= fmin + 2*range/6 then
       return ([1, abs(-cos((c-fmin)*(PI/2)/(range/6))^a), 0])   //([abs(sin((c-fmin)*(PI/2)/(range/6))^a), 1, 0])
    elif c <= fmin + 3*range/6 then
       return ([abs(cos((c-fmin)*(PI/2)/(range/6))^a), 1, 0])   //([0, 1, abs(-sin((c-fmin)*(PI/2)/(range/6))^a)]) 
    elif c <= fmin + 4*range/6 then
       return ([0, 1, abs(cos((c-fmin)*(PI/2)/(range/6))^a)])   //([0, abs(-sin((c-fmin)*(PI/2)/(range/6))^a), 1])  
    elif c <= fmin + 5*range/6 then
       return ([0, abs(cos((c-fmin)*(PI/2)/(range/6))^a), 1])  //([abs(sin((c-fmin)*(PI/2)/(range/6))^a), 0, 1])
    elif c <= fmin + 6*range/6 then
       return ([abs(-cos((c-fmin)*(PI/2)/(range/6))^a), 0, 1])   //([1, 0, abs(sin((c-fmin)*(PI/2)/(range/6))^a)])
    else 
       return ([abs(-cos((c-fmin)*(PI/2)/(range/6))^a), 0, 1])
  end_if
end_proc:

  colfunc := (x,y,z) -> colour(arctan(z)/(0.5*PI*1.4)): //the factor of 1.4 prevents the spectrum from wrapping around to magenta 
                                                        //and ensures the spectrum stops at red and blue

  
  cplot := plot::Density(f, 
                         x = -xlimit..xlimit, 
                         y = -ylimit..ylimit, 
                         AntiAliased = TRUE,
                         Mesh = [mesh, mesh],
                         AxesTitleFont = ["Courier New", Bold, 14],
                         TicksLabelFont = ["Arial", 10],
                         FillColorFunction = colfunc,
                         YTicksDistance = 0.5,
                         XTicksDistance = 0.5):
  
  plot(cplot,
       Axes = Frame,
       Width = 8.5*unit::inch, 
       Height = 7*unit::inch):

.

Here's the grenn-centred spectrum that I was using, with a picture:

a := 1:
r := plot::Function2d(piecewise([x<60,1],[x>60 and x<120, 1],[x>120 and x<180, -cos(PI*x/120)^a],[x>180 and x<300, 0],[x>300 , -cos(PI*x/120)^a]), LineColor=RGB::Red, LineWidth=0.7,x=0..360):
g := plot::Function2d(piecewise([x<60,0],[x>60 and x<120, -cos(PI*x/120)^a],[x>120 and x<240, 1],[x>240 and x<300, abs((cos(PI*x/120))^a)],[x>300, 0]), LineColor=RGB::Green, LineWidth=0.7,x=0..360):
b := plot::Function2d(piecewise([x<60,abs(cos(PI*x/120)^a)],[x>60 and x<180, 0],[x>180 and x<240, abs((cos(PI*x/120))^a)],[x>240, 1]), LineColor=RGB::Blue, LineWidth=0.7,x=0..360):
c1 := ((x) -> [1, 0,abs(cos(PI*x/120)^a)]):
c2 := ((x) -> [1,abs(-cos(PI*x/120)^a),0]):
c3 := ((x) -> [abs(-cos(PI*x/120)^a), 1,0]):
c4 := ((x) -> [0,1,abs((cos(PI*x/120))^a)]):
c5 := ((x) -> [0,abs((cos(PI*x/120))^a),1]):
c6 := ((x) -> [abs(-cos(PI*x/120)^a),0,1]):
T1 := plot::Function2d(cos(30*PI*x)/2+2, LineColorFunction=c1, LineWidth=1,x=0..60):
T2 := plot::Function2d(cos(30*PI*x)/2+2, LineColorFunction=c2, LineWidth=1,x=60..120):
T3 := plot::Function2d(cos(30*PI*x)/2+2, LineColorFunction=c3, LineWidth=1,x=120..180):
T4 := plot::Function2d(cos(30*PI*x)/2+2, LineColorFunction=c4, LineWidth=1,x=180..240):
T5 := plot::Function2d(cos(30*PI*x)/2+2, LineColorFunction=c5, LineWidth=1,x=240..300):
T6 := plot::Function2d(cos(30*PI*x)/2+2, LineColorFunction=c6, LineWidth=1,x=300..360):
plot(r(x), g(x), b(x),
T1,T2,T3,T4,T5,T6,
ViewingBox = [0..360, 0..3])

Cheers,

Inductiveload 21:28, 24 April 2007 (UTC)

First off ,sorry, i meant 15 minutes, but missed of the 1, and it was an estimate. Becuase I do other things like weatch TV and do my work that I should be doing, time tends to blur a bit. It could be even longer. Also, this new function seems to take longer - it just took me about 40 mins for a 1000x1000 plot, and I have quite a fast processor. I haven't completed a 1500x1500 render yet.

Isn't Image:Surface-plot.png the same as that parabolic cylinder thing you found on MathWorld? It's certainly the same idea.

It cycles red-yellow becuase it repeats the last segment again (red increasing, blue=1, green=0). You could change it so that the final else statement ran

   else 
      return ([1, 0, 1])

And the same for the first. This means that when it gets to the end, it doesnt change any more. That's a good modification, actually, to reduce complexity. I haven't tried it yet, but I will for my next render. When I say cycle, i meant around the spectrum. If you look at the green-centred spectrum here, you will see that it is magenta at both ends. If you took the number modulo (fmax-fmin), then you could possiblyget cycling round and round, but that would be even less clear, as it would look like it goes down to zero again (when it gets to green) and then back up. Without that, the coulours wont actually cycle. Remember that HSV colours are done by angles, which start again at 360=0, and the program can interpret this.

I think the thing where it gets stuck on yellow and cyan is due to the fact that there are only three major colours to use on each side:

  • Green-cyan-blue for negative
  • Green-yelolow-red for positive

So the areas are bound to be wide. Remember that this area of the graph is quite flat, so not much changes. The inclusion of the arctan is meant to help that by over-representing the small numbers in terms of change (without cycling). If you have arctan(x*2) instead (say) then the area near zero will change more than the large areas. This will give a larger red and blue areas, and faster change in the green area. I'll do you a plot of that next. If you think that a needs to be bigger, you tell me, because I can't tell!

As for the HSL thing, you wouldnt even need to do that. HSV can be made to go black and white (v=0 -> black, s=0 ->white). I'll look into making small singularities black and large ones white. Another set of elif's in the procedure should do it (say once abs(z)>20). I'll do one of those too. Give me a while to do it - this function seems to be slooooow!

Hope this makes sense!

Edit: Here's the arctan(2*x) one: here. This took 118 seconds there's a timer built into MuPAD - put this at the end:

  time((plot(cplot,
             Axes = Frame,
             Width = 8.5*unit::inch, 
             Height = 7*unit::inch)))*sec/1000.0


Inductiveload 22:16, 24 April 2007 (UTC)

Done the black and white one. Rember that HSV-RGB function? - seems to work here. Here's the important code:

colour := proc(c)
 begin
    if   c <  fmin then
       return (RGB::fromHSV([0, 1, 1/abs(c)])) 
    elif c <= fmin + 1*range/4 then
       return ([1, abs(sin((c-fmin)*(PI/2)/(range/4))^a), 0])  //R-Y
    elif c <= fmin + 2*range/4 then
       return ([abs(sin((c-fmin)*(PI/2)/(range/4))^a), 1, 0])   //y-G
    elif c <= fmin + 3*range/4 then
       return ([0, 1, abs(-sin((c-fmin)*(PI/2)/(range/4))^a)])   //g-c
    elif c <= fmin + 4*range/4 then
       return ([0, abs(-sin((c-fmin)*(PI/2)/(range/4))^a), 1])   //c-b
    else 
       return (RGB::fromHSV([240, 1/abs(c), 1]))//([1, 0, arctan(c/20)*255/(PI/2)])
  end_if
end_proc:

  colfunc := (x,y,z) -> colour(z): 

Note that the colour scheme is linear in the middle. Also, it will never go to magenta. Fmin is -1 and fmax is 1. I'll have a look at doing. By changing it, you can adjust what counts as a singularity, and how big the white/black zones are. For somereason as 200x200 plot ony took 47 seconds just now. Maybe this function is faster, but its very significant...

Inductiveload 23:36, 24 April 2007 (UTC)

Ok, here's one with a -5 -> 5 linear region and white and black past that. You can see here why the arctan is quite good- without it the region near 0 is all green with no detail. Here's the code.

 f := Im(exp(1/(x+I*y))):

  ylimit := 1:
  xlimit := 1:
  mesh := 200:     //resolution of density plot
   
a:=1:              //change this to adjust the colour band drop-of rate
fmin := -5:        //minimum value of colour function before fade to black starts
fmax :=  5:        //maximum value of colour function before fabe to white starts
range:=fmax-fmin:  //for brevity
  
colour := proc(c)
 begin
    if   c <  fmin then
       return (RGB::fromHSV([0, 1, fmin/c])) 
    elif c <= fmin + 1*range/4 then
       return ([1, abs(sin((c-fmin)*(PI/2)/(range/4))^a), 0])  //R-Y
    elif c <= fmin + 2*range/4 then
       return ([abs(sin((c-fmin)*(PI/2)/(range/4))^a), 1, 0])   //y-G
    elif c <= fmin + 3*range/4 then
       return ([0, 1, abs(-sin((c-fmin)*(PI/2)/(range/4))^a)])   //g-c
    elif c <= fmin + 4*range/4 then
       return ([0, abs(-sin((c-fmin)*(PI/2)/(range/4))^a), 1])   //c-b
    else 
       return (RGB::fromHSV([240, fmax/c, 1]))
  end_if
end_proc:

  colfunc := (x,y,z) -> colour(z): 

  
  cplot := plot::Density(f, 
                         x = -xlimit..xlimit, 
                         y = -ylimit..ylimit, 
                         AntiAliased = TRUE,
                         Mesh = [mesh, mesh],
                         AxesTitleFont = ["Courier New", Bold, 14],
                         TicksLabelFont = ["Arial", 10],
                         FillColorFunction = colfunc,
                         YTicksDistance = 0.5,
                         XTicksDistance = 0.5):
  
  time((plot(cplot,
             Axes = Frame,
             Width = 8.5*unit::inch, 
             Height = 7*unit::inch)))*sec/1000.0

notice fmax and fmin in the if statements - that's realy important to get the zones to line up.

I'll get a really high res one of the absolute values for you tomorrwo (i'll leave it on overnight). also - I just realised that i wrote range:=zmax-zmin, when i meant range:=fmax-fmin - is this why you're havng problems with some things?

Ok, update: I'm seriouslyt having problems trying to get a non-linearity into the code to get more detail around zero, i've been trying for ages now. I'm not sure about the black and white thing anyway - i quite like them without. Perhaps its just becuase such large area are black and white. I dont know what I'm doing wrong, but I haven't really come up wth anythng useful. It's late in London too, so maybe I'm just tired!

As for the absolute value density plot - I'll do one that has red at zero and then goes up through yellow, green, cyan to blue. (So in order of the light spectrum). I might do one with arctan(2*x) too, just to see. I'll upload both whatever.

Inductiveload

High-res stuff

Here is a 1000x1000 plot of the absolute imag part. For some reason, this only took 370 seconds, by the way, I can't work out why the time fluctuates so much - I'm not doing anything else on the computer. Strange.

Here is the same plot but based on a green=0, magenta centred spectrum.

I think I prefer the red one, like you said, but I'm not sure.

Here is the code for the red one:

 f := abs(Im(exp(1/(x+I*y)))):

  ylimit := 1:
  xlimit := 1:
  mesh := 1000:     //resolution of density plot
   
a    := 1:   //change this to adjust the colour band drop-of rate
fmin := 0:  //minimum value of colour function (i.e the one with arctan in it)
fmax := 1:  //maximum value of colour function
range:= 1:  //for brevity
  
colour := proc(c)
 begin
    if   c <  fmin then
       return ([1, 0, 0])  //this term may not be needed, but it means we can deal with slightly under-limit values
    elif c <= fmin + 1*range/6  then 
       return ([1, abs(sin((c-fmin)*(PI/2)/(range/6))^a), 0])
    elif c <= fmin + 2*range/6 then
       return ([abs(sin((c-fmin)*(PI/2)/(range/6))^a), 1, 0])
    elif c <= fmin + 3*range/6 then
       return ([0, 1, abs(-sin((c-fmin)*(PI/2)/(range/6))^a)]) 
    elif c <= fmin + 4*range/6 then
       return ([0, abs(-sin((c-fmin)*(PI/2)/(range/6))^a), 1])  
    elif c <= fmin + 5*range/6 then
       return ([abs(sin((c-fmin)*(PI/2)/(range/6))^a), 0, 1])
    elif c <= fmin + 6*range/6 then
       return ([1, 0, abs(sin((c-fmin)*(PI/2)/(range/6))^a)])
    else 
       return ([1, 0,1])
  end_if
end_proc:

  colfunc := (x,y,z) -> colour(arctan(z/2)*(5.0001/6)/(0.5*PI)): //the factor of 5/6 prevents the spectrum from wrapping 
                                                                // by precisely one colour transition (m->r). 
                                                                //The extra 0.0001 is to prevent an error when evaluating the 5th elif clause. 
                                                                //No idea why, but it must be sometihng to do with there being a 5/6 in there.

  
  cplot := plot::Density(f, 
                         x = -xlimit..xlimit, 
                         y = -ylimit..ylimit, 
                         AntiAliased = TRUE,
                         Mesh = [mesh, mesh],
                         AxesTitleFont = ["Courier New", Bold, 14],
                         TicksLabelFont = ["Arial", 10],
                         FillColorFunction = colfunc,
                         YTicksDistance = 0.5,
                         XTicksDistance = 0.5):
  
  time((plot(cplot,
             Axes = Frame,
             Width = 8.5*unit::inch, 
             Height = 7*unit::inch)))*sec/1000.0

Here is the code for the green one:

 f := abs(Im(exp(1/(x+I*y)))):

  ylimit := 1:
  xlimit := 1:
  mesh := 1200:     //resolution of density plot
   
a    := 1:   //change this to adjust the colour band drop-of rate
fmin := 0:  //minimum value of colour function (i.e the one with arctan in it)
fmax := 1:  //maximum value of colour function
range:= 1:  //for brevity
  
colour := proc(c)
 begin
    if   c <  fmin then
       return ([0, 1, abs(sin((c-fmin)*(PI/2)/(range/6))^a)])  //this term may not be needed, but it means we can deal with slightly under-limit values
    elif c <= fmin + 1*range/6  then 
       return ([0, 1, abs(sin((c-fmin)*(PI/2)/(range/6))^a)])
    elif c <= fmin + 2*range/6 then
       return ([0, abs(sin((c-fmin)*(PI/2)/(range/6))^a), 1])
    elif c <= fmin + 3*range/6 then
       return ([abs(-sin((c-fmin)*(PI/2)/(range/6))^a), 0, 1]) 
    elif c <= fmin + 4*range/6 then
       return ([1, 0, abs(-sin((c-fmin)*(PI/2)/(range/6))^a)])  
    elif c <= fmin + 5*range/6 then
       return ([1, abs(sin((c-fmin)*(PI/2)/(range/6))^a), 0])
    elif c <= fmin + 6*range/6 then
       return ([abs(sin((c-fmin)*(PI/2)/(range/6))^a), 1, 0])
    else 
       return ([0, 1, 0])
  end_if
end_proc:

  colfunc := (x,y,z) -> colour(arctan(z/2)*(5.0001/6)/(0.5*PI)): //the factor of 5/6 prevents the spectrum from wrapping 
                                                                // by precisely one colour transition (m->r). 
                                                                //The extra 0.0001 is to prevent an error when evaluating the 5th elif clause. 
                                                                //No idea why, but it must be sometihng to do with there being a 5/6 in there.

  
  cplot := plot::Density(f, 
                         x = -xlimit..xlimit, 
                         y = -ylimit..ylimit, 
                         AntiAliased = TRUE,
                         Mesh = [mesh, mesh],
                         AxesTitleFont = ["Courier New", Bold, 14],
                         TicksLabelFont = ["Arial", 10],
                         FillColorFunction = colfunc,
                         YTicksDistance = 0.5,
                         XTicksDistance = 0.5):
  
  time((plot(cplot,
             Axes = Frame,
             Width = 8.5*unit::inch, 
             Height = 7*unit::inch)))*sec/1000.0

Here is the code for the green spectrum plot:

a := 1:
r := plot::Function2d(piecewise([x<120,0],[x>120 and x<180, abs(sin(PI*x/120)^a)],[x>180 and x<300, 1],[x>300, sin(PI*x/120)^a]), LineColor=RGB::Red, LineWidth=0.7,x=0..360):
g := plot::Function2d(piecewise([x<60,1],[x>60 and x<120, sin(PI*x/120)^a],[x>120 and x<240, 0],[x>240 and x<300, abs((sin(PI*x/120))^a)],[x>300, 1]), LineColor=RGB::Green, LineWidth=0.7,x=0..360):
b := plot::Function2d(piecewise([x<60,abs(sin(PI*x/120)^a)],[x>60 and x<180, 1],[x>180 and x<240, abs((sin(PI*x/120))^a)],[x>240, 0]), LineColor=RGB::Blue, LineWidth=0.7,x=0..360):
c1 := ((x) -> [0, 1, abs(sin(PI*x/120)^a)]):
c2 := ((x) -> [0, abs(sin(PI*x/120)^a),1]):
c3 := ((x) -> [abs(-sin(PI*x/120)^a), 0,1]):
c4 := ((x) -> [1,0,abs((-sin(PI*x/120))^a)]):
c5 := ((x) -> [1,abs((sin(PI*x/120))^a),0]):
c6 := ((x) -> [abs(sin(PI*x/120)^a),1,0]):
T1 := plot::Function2d(cos(30*PI*x)/2+2, LineColorFunction=c1, LineWidth=1,x=0..60):
T2 := plot::Function2d(cos(30*PI*x)/2+2, LineColorFunction=c2, LineWidth=1,x=60..120):
T3 := plot::Function2d(cos(30*PI*x)/2+2, LineColorFunction=c3, LineWidth=1,x=120..180):
T4 := plot::Function2d(cos(30*PI*x)/2+2, LineColorFunction=c4, LineWidth=1,x=180..240):
T5 := plot::Function2d(cos(30*PI*x)/2+2, LineColorFunction=c5, LineWidth=1,x=240..300):
T6 := plot::Function2d(cos(30*PI*x)/2+2, LineColorFunction=c6, LineWidth=1,x=300..360):
plot(r(x), g(x), b(x),
T1,T2,T3,T4,T5,T6,
ViewingBox = [0..360, 0..3])

Notice the arctan(x/2), that helps to make the colours distribute nicely (otherwise the zero colour band is too wide). What do you think?

Also, here is a old thing I did (the first use for this colour function). It just translates height into the colour. I described it already and gave code, but here's a pic anyway.

Inductiveload

Hey there - quick update - here's a plot of your gamma function with the new colours (no magenta-red banding, and arctan(x/2)). What do you think? (It a 1500x1500 plot).

yeasa i agreee

very much so !!!!!!!! +P+P+P+P=p=p=p=p=p=p —The preceding unsigned comment was added by 217.42.71.146 (talk) 14:56, 4 May 2007 (UTC).

Yeah, thanks for the vandalism. You must've spent more time doing it than me reverting. Silly. -Xedi 16:00, 4 May 2007 (UTC)

Image:Seraphim Logo.png

Greetings, I just though I would let you know I have created an SVG version of the logo. Fosnez 02:14, 29 September 2007 (UTC)

Graphs

Hi I was just wondering what program you used to make graphs like this (http://en.wikipedia.org/wiki/Image:RationalDegree2byXedi.gif). Thanks. somody 11:06, 22 October 2007 (UTC)