zenterix

310 Reputation

4 Badges

3 years, 97 days

MaplePrimes Activity


These are replies submitted by zenterix

@Carl Love no output at all (if this were in the worksheet I would be sure nothing was imported). Is there some unique initialization file for the CLI that tells it where to look for packages that is different from the one worksheets use?

@acer 

Here are the steps I took to try to find the answer to this question.

1) Google "maple 3d plot lighting".

2) The first entry is a Maple page with the title "Change Lighting". The main content shows how to change lighting using the context menu. There are two links: "Lighting Schemes" and "Changing Lighting". After clicking I realize they are links to the content below.

On the right-hand side are other links but it is not clear which, if any, will be useful for this task. I settle for the link "plot3d/options".

3) I search the new page ("Options for 3-D Plots") for "lighting". There is one result, inside the option "ambientlight", which is set with a list [r, g, b]. I tried in Maple with [0, 0, 0] and [1, 1, 1]. 

I just noticed that this works (before I asked this question I tried out this command, but I tried with values [255, 255, 255], unfortunately. [1,1,1] works perfectly.

After reading the answers above, I searched for "light" and found "lightmodel". This is the actual desired solution based on the experience with the UI.

Honestly, though, one should be able to search for "lighting", just as it appears in the UI context menu. 

Everyone is different. That's why building a UI is such a mix of science and art form. Making it simple and elegant and useful for all users to find what they want. Writing documentation, I would argue, is the same way.

@acer Do you think it would be a worthwhile side project to write a library for matrix manipulation? Or is there already one and I am not aware of it?

There are all sorts of matrix manipulations that one could want to do, as we see with, for example pandas and numpy in python.

For example, how do we obtain a new matrix with the rows sorted based on a specific column?

@acer Here is my solution putting everything you've described together


 

read "./matrix.m"

First let's do two test cases

m1

_rtable[36893488152056066348]

(1)

max(m1[..,1])

120

(2)

10200/120

85

(3)

surfM1 := `<,>`(seq(`<|>`(seq(m1[i][3], i=j..10200, 120)), j=1..120)):

LinearAlgebra:-Dimension(surfM1)

120, 85

(4)

plots:-surfdata(surfM1, min(m1[..,1])..max(m1[..,1]), min(m1[..,2])..max(m1[..,2]), dimension=2, style=surface, colorscheme=["zgradient", ["Red", "Magenta"], colorspace="HSV"])

 

Here is a similar case, but now the first column has a step of 0.5.

read "./m2.m"

ch2

_rtable[36893488152056066956]

(5)

maxColumn1 := max(ch2[..,1])

300.0

(6)

step := ch2[1,1]

.5

(7)

surfCh2 := `<,>`(seq(`<|>`(seq(ch2[i][3], i=j..17400, trunc(maxColumn1/step))), j=1..trunc(maxColumn1/step))):

LinearAlgebra:-Dimension(surfCh2)

600, 29

(8)

whattype(surfCh2)

Matrix

(9)

plots:-surfdata(surfCh2, min(ch2[..,1])..max(ch2[..,1]), min(ch2[..,2])..max(ch2[..,2]), dimension=2, style=surface, colorscheme=["zgradient", ["Red", "Magenta"], colorspace="HSV"])

 

ArrayTools:-Size(ch2)

Vector[row](2, {(1) = 17400, (2) = 3})

(10)

Here is a procedure that does everything in one go.

plotDensity := proc(arr)
  local rows, maxColumn1, minColumn1, maxColumn2, minColumn2, step, xPoints, surfM, i, j:
  rows := ArrayTools:-Size(arr)[1]:
  maxColumn1 := max(arr[..,1]):
  minColumn1 := min(arr[..,1]):
  maxColumn2 := max(arr[..,2]):
  minColumn2 := min(arr[..,2]):
  step := arr[2,1] - arr[1,1]:
  xPoints := trunc(maxColumn1/step):
  surfM := `<,>`(seq(`<|>`(seq(arr[i][3], i=j..rows, xPoints)), j=1..xPoints)):
  plots:-surfdata(surfM, minColumn1..maxColumn1, minColumn2..maxColumn2, dimension=2, style=surface, colorscheme=["zgradient", ["Red", "Magenta"], colorspace="HSV"])
end:  

 

plotDensity(ch2)

 

plotDensity(m1)

 

NULL

NULL

NULL


 

Download DensityPlot.mw

Here are the compressed files with the matrices: DensityPlot.zip

@acer 

Yes the data is structured in a simliar way. For example, the first column has rows that go from, say, 1 to 10 twelve times. The first values x from 1 to 10 are associated with some value y1 in the second column.

The second values x 1 to 10 are associated with some value y2 in the second column.

And so on.

The value in the third column represents f(x,y).

I agree that spending the time to format the matrix/array in a way that works with, say, surfdata is best. 

It's just that there is no top-level easy manipulation of array/matrix in Maple. Everything has to be done with these convoluted commands (as opposed to libraries in other languages). 

I will try now.

@acer Is there a way to set the range for the x-axis when using listdensityplot?

Below is an example, based on your worksheet above.

Note that with plots:-surfdata I can set the range (the x values go from 0.5 to 300 with a step of 0.5). listdensityplot shows a range of 1 to 600. I can't figure out how to set this range from the documentation.

restart;

currentdir(cat(kernelopts(homedir), "/mapleprimes")):

convertArrayToTable := proc(arr)
        local m, t, i, c1, c2, c3:
        m := ArrayTools:-Size(arr)[1]:
        t := table([]):
        for i from 1 to m do:
                c1 := arr[i,1]:
                c2 := arr[i,2]:
                c3 := arr[i,3]:
                if not assigned(t[HFloat(c1)]) then:
                        t[HFloat(c1)] := table([ HFloat(c2) = c3]):
                else:
                        t[HFloat(c1)][HFloat(c2)] := c3:
                end:
        end:
        return eval(t);
end:

 

read "./m2.m":
m1 := Matrix(ch2,datatype=float[8]):

 

m1

_rtable[36893488151903420532]

(1)

T := convertArrayToTable(m1):

TIndices := [indices(T,nolist)]:

TI := sort([indices(T[HFloat(1)],nolist)]):

MMM:=`<,>`(seq(`<|>`(seq(T[ii][vv],
                         vv=sort([indices(T[ii],nolist)]))),
               ii=sort([indices(T,nolist)]))):

print(MMM)

_rtable[36893488151962357876]

(2)

plots:-listdensityplot(MMM,colorstyle=HUE,style=surface,
                       ytickmarks=[1=TI[1],seq(10*i=TI[10*i],
                                               i=1..iquo(nops(TI),10))]);

 

plots:-surfdata(MMM,min(TIndices)..max(TIndices),min(TI)..max(TI),
                dimension=2,style=surface,
                colorscheme=["zgradient",["Red","Magenta"],
                             colorspace="HSV"]);

 

 

NULL

Download table-hfloat_ac.mw

@acer Thanks, I will go with the simplest option for now. I need time to learn about some of the syntax in the other options.

@acer Ok, no problem, I've added my new question as a new comment to this thread.

Before going into details, here is a quick version of my question: I have a density plot that has incorrect display (the two red streaks) because data is not being read correctly for two specific keys in a table:

Those two red streaks are incorrect. 

I did a bit of debugging and I found what the issue is. My current question, and the reason for this post, is about why the issue is happening. It has to do with accessing values from a table where the keys are of type HFloat.

I will now try to succintly describe the issue, but I have also created a worksheet that reads the matrix with the data for the density plot above, converts the matrix to a table, and then creates the density plot. 

These files can be access in a Github repo I created, or as a .zip file attached to this post: table-hfloat.zip

Details

A couple weeks ago, the original question in this entire thread was about how to take an n x 3 matrix and "convert" it to a nested table. Let me recall briefly what this table looks like.

In the outer table, the first column of the matrix are the keys.

This first column can have repeated elements. For each such key, the associated value is a table. This inner table contains as keys the values from the second column of the matrix that have the outer key as the first column in the matrix.

The values associated with each inner key is just the value in the third column of the matrix.

Now, in my other question, I was having trouble with this, but the issue was that the inner keys were floating point numbers. To make the creation of this table work, I converted all keys to HFloat. Then, when accessing keys in the table, I would also type cast to HFloat.

For example, let's say the table is called T and in the matrix there is a row with values 50, 0.95, 3 and another row with values 50, 0.945, 4.

Then we should be able to access T[HFloat(50)][HFloat(0.95)] and get 3, and T[HFloat(50)][HFloat(0.9450)] and get 4.

For the record, each row represents x, y, and z coordinates. 

The points represented by the first two columns form a grid. 

The Issue

I created a simple procedure that takes x and y values and returns T[HFloat(x)][HFloat(y)]. I then pass this procedure to plots:-densityplot so that it can get the values it needs.

This works perfectly, except that for some reason there are two inner keys that don't work: 0.945 and 0.9925.

From the density plot pictured above, you can see that the grid is for values of x between 0 and 120, and values of y between 0.90 and 1.11. Every single access of the table works except at values of y of 0.945 and 0.9925, and this is why we get those two red streaks.

I confirmed this by printing out every single attempt at accessing the table.

Why the heck does the access not work for these two values? The linked repo contains all the actual computations in Maple.

One more thing. Weirdly, this works: T[HFloat(50)][HFloat(0.9450000000)]

Ie, I deleted five zeros from the end of the number.

HFloat(0.945000000000000) and HFloat(0.9450000000) seem to produce the same result in Maple.

However, 

evalb(HFloat(0.945000000000000) = HFloat(0.9450000000))

results in false, even though if I change the 4 to a 7 then it results in true. 

@acer Indeed I have no idea how that hidden execution group got in there but it was absolutely maddening. 

I will only use the usual execution groups with the red arrows from now on with 1d input.

@acer In hindsight the issue was with the hardware floats. But from the perspective of the person asking the question (who at the time did not know of the existence of that data type in Maple), a description of the problem was necessarily more general. 

Regarding the second original example

I wrote: "Here is a proof of concept of what I am trying to achieve (note that below, I am avoiding the issue of the decimal keys in tables by using integers instead):"

Now, the definition of proof of concept is: "evidence, typically derived from an experiment or pilot project, which demonstrates that a design concept, business proposal, etc., is feasible.

So, to show that my ultimate goal (a density plot based on a matrix that has been converted to a table) was feasible, I used integers (because, by the first part, with decimals it was not working). In fact, this second part was to show that the whole endeavor would not be fruitless if I were to solve the first part (the floating point issue part).

In hindsight, I still think that had I only shown the first code snippet (where I asked simply how to access a particular float key in a table), the solution to that issue would have been enough to solve the real problem. 

After all the solution so far has been to define the table by type casting to HFloat in convertArrayToTable, and then when accessing the key to also type cast. Both of these elements fix the very first example.

Anyways, I'm glad that its ok to post super detailed (and probably longer) questions here and it won't turn people off. So I'll try to do that in the future, without trying to simplify things too much (this strategy is one that I came up with based on how people respond to my hundreds of math questions on Stack Exchange, where people seem to answer short questions more than longer questions).

Thanks again

@acer The thing is, I try to identify exactly what the issue is in the middle of a bigger problem, and then ask a question about that specific issue. In this instance, the issue was of accessing an entry in a table with a decimal key.

And as far as I can tell from your solution, indeed the issue in both cases I presented boiled down to this one thing.

Your final solution worked, thank you.

@acer Your solution using trunc worked for the example I gave with integers. 

The real use case, however, is the first one with the decimal number keys. Here is an example of the problem

restart

  convertArrayToTable := proc(arr)
        local m, t, i, c1, c2, c3:

        m := ArrayTools:-Size(arr)[1]:
        t := table([]):

        for i from 1 to m do:
                c1 := arr[i,1]:
                c2 := arr[i,2]:
                c3 := arr[i,3]:

                if not assigned(t[c1]) then:
                        t[c1] := table([ c2 = c3]):
                else:
                        t[c1][c2] := c3:
                end:
        end:
        print(t):

        return t:
end:NULL

A := Matrix([[1, .2, 3], [2, .2, 6], [3, .2, 9], [4, .2, 12]])

Matrix(%id = 36893488151929928628)````

(1)

B := ArrayTools:-Concatenate(1, A, Matrix(`<|>`(A[1 .. (), 1], 2*A[1 .. (), 2], 2*A[1 .. (), 3])), Matrix(`<|>`(A[1 .. (), 1], 3*A[1 .. (), 2], 3*A[1 .. (), 3])), Matrix(`<|>`(A[1 .. (), 1], 4*A[1 .. (), 2], 4*A[1 .. (), 3])))

_rtable[36893488151929880812]NULL

(2)

T := convertArrayToTable(B)

t``

(3)

NULL

f := proc (x, y) global T; print(x, y, " Returning ", T[x][y]); return T[x][y] end proc

g := proc (ix, iy) local x, y; global T; x := trunc(ix); y := trunc(iy); print(x, y, " Returning ", T[x][y]); return T[x][y] end proc

plots:-densityplot(f, 1 .. 4, .2 .. .8, grid = [5, 5])

Error, (in Plot:-ColorScheme) unable to produce gradient shading from given data

 

 

Download convertArrayToTable.mw

What are the workarounds that you mentioned?

When we print the table in Maple it shows the keys and values. It's weird that I can't just copy one such key 0.400000000000000 and use that as the key. I have to know the specific type being used for this number?

@mmcdara Interesting. Multiple ways to do the same thing it appers.

I am working on some problems in electromagnetism, which involves a lot of multivariable calculus and constants that are multiples of very negative powers of 10. I don't want to work with the values of the constants, I want to work with the symbolic terms. I am integrating more complicated vectors than the simple example I gave.

@mmcdara A lot of times my questions end up being answered with: it works in 1d math input but not 2d math input. Your worksheet contains 1d math. Perhaps you could try with 2d math. Like with my original worksheet (which definitely does contain a plotting command; all you have to do is change the [-2,1] to anything else like [-2,2] and it will plot the vector).

1 2 3 4 5 6 Page 2 of 6