PlotLegends makes Manipulate[] ing graphs slow to a crawl - wolfram-mathematica

I have a short program set up to display three plots of the same function with different parameters using Manipulate. I'd like to label each function with the value of the parameter. My starting point was to just get a legend to show up at all. Adding a PlotLegend to the plot causes Mathematica to become unusably slow.
My code is:
Needs["PlotLegends`"]
Manipulate[
UemaxOverUe = ((VA/Vphs)^2 (2 p - 1) + 1 - Ves0/Vphs - 2)/((VA/Vphs)^2 - (1 - Ves0/Vphs));
UemaxOverUe2 = ((VA/Vphs)^2 (2 p - 1) + 1 - Ves02/Vphs - 2)/((VA/Vphs)^2 - (1 - Ves02/Vphs));
UemaxOverUe3 = ((VA/Vphs)^2 (2 p - 1) + 1 - Ves03/Vphs - 2)/((VA/Vphs)^2 - (1 - Ves03/Vphs));
ListPlot[{
Table[{Vphs/VA, 1/UemaxOverUe}, {Vphs, .001 VA, VA, .01 VA}],
Table[{Vphs/VA, 1/UemaxOverUe2}, {Vphs, .001 VA, VA, .01 VA}],
Table[{Vphs/VA, 1/UemaxOverUe3}, {Vphs, .001 VA, VA, .01 VA}]},
AxesLabel -> {"Vphs/VA", "Ne/NeMax"}, Joined -> True(*,
PlotLegend->{"Blah","Blarg","Word"}*)],
{{p, 1}, 0, 5},
{{Ves0, -2 VA}, -10 VA, 10 VA, .1 VA},
{{Ves02, -2 VA}, -10 VA, 10 VA, .1 VA},
{{Ves03, -2 VA}, -10 VA, 10 VA, .1 VA}
]
Uncommenting the PlotLegend should recreate the problem.
My questions are:
Why does this happen?
What is a good solution, or workaround?

The problem seems to be that PlotLegend is just slow. It hasn't got anything to do with Manipulate. On my PC The ListPlot takes 0.013 s without a legend and 0.43 second if a legend is added.
As a workaround you could use
ControlActive[{}, PlotLegend -> {"Blah", "Blarg", "Word"}]]
instead of just the PlotLegend to show the legend only when you're not moving the sliders.

An alternative to Sjoerd's answer might be to reconstruct the legend as an Epilog, given that you know you have three series to plot.

Related

Plot 2-d data in Matlab [duplicate]

This question already has an answer here:
Creating colormap at specific point and color weights at matlab
(1 answer)
Closed 5 years ago.
I have data like this :
x coordinate| y coordinate | Z
0.01 | 0.15 | 1
0.23 | 0.17 | 5
0.28 | 0.18 | 6
... ... ...
I want to plot all of these data in 2-d such that , in each point (x,y)
we have the corresponding intensity Z which i want to be depicted with a colour . Just like the function 'image' which already exists . But i have a problem that the aforementioned function of matlab plot in a uniform manner all the points. So if i have
x= [0 0.01 1];
y = [0 1];
'Z = [1 1 0;0 1 1];'
Then it will plot the corresponding densities at the (0,0) (0.5,0) , (1 ,0)... So it takes the max of x and the min of x and take uniform pieces .
I want to plot my data in specific points.
Any ideas , is there any other suitable function for this ?
How can i construct something like that ?
If your data is a grid that has sligth variations on the values, but still a grid, do:
surf(x,y,z,'linestyle','none');
axis tight;axis off; view(2)
Example output with
z=peaks;
[x,y]=meshgrid(1:49,1:49);
x=x+rand(size(x))*0.1;
y=y+rand(size(x))*0.1;

What is the best time complexity possible to find a solution to x^2 + y^2 = m where m can be any natural number?

I have to find a solution to the equation x2 + y2 = m where m can be any natural number and x,y are integers. This can be done in O(m1/2) by using brute force easily. Is there a way I can do this in constant time?
I'm not sure you can do it any better than O(sqrt(m)) for an arbitrary m but that's pretty damn good , much better than linear time :-)
The approach is to start x and y at opposite ends of the solution space and either increment the low end or decrement the high end, depending on whether the result is too low or too high (obviously if the result is perfect, return the values):
def solveForM(m):
set lo to 0
set hi to sqrt(m), rounded up.
while lo < hi:
testVal = lo * lo + hi * hi
if testVal == m:
return (lo, hi)
if testVal > m:
hi = hi - 1
else lo = lo + 1
return "No solution"
If m can be limited somehow, you could achieve O(1) by use of a lookup table (many optimisations come down to trading space for time), such as:
0 -> 0, 0
1 -> 0, 1
2 -> 1, 1
No solution for 3
4 -> 0, 2
5 -> 1, 2
No solution for 6, 7
8 -> 2, 2
9 -> 0, 3
10 -> 1, 3
No solution for 11, 12
13 -> 2, 3
... and so on.
A table like this can be generated with a small program along the lines of (Python 3):
for hi in range(1001):
for lo in range(1001):
m = lo * lo + hi * hi
print("%5d -> %d, %d"%(m, lo, hi))
You have to sort (and possibly remove duplicates) afterwards to create a fast look-up table but the performance is okay with the generation of an unsorted list taking fifteen seconds for all m up to two million.
In any case, this is only run once, after which you would place the table into code where the time expense is incurred at compile time.

Subtracting row 2 from row 1 repeatedly

I want to create in R a column in my data set where I subtract row 2 from row1, row 4 from row 3 and so forth. Moreover, I want that the subtraction result is repeated for each row (e.g.if the result from the subtraction row2-row1 is -0.294803, I want this value to be present both in row1 and row2, hence repeated twice for both factors of the subtraction, and so forth for all subtractions).
Here my data set.
I tried with the function aggregate but I didn't succeed.
Any hint?
Another possible solution can be:
x <- read.table("mydata.csv",header=T,sep=";")
x$diff <- rep(x$log[seq(2,nrow(x),by=2)] - x$log[seq(1,nrow(x),by=2)], each=2)
By using the function seq(), you can generate the sequences of row positions:
1, 3, 5, ... 9
2, 4, 6, ... 10
Afterwards, the code subtracts the rows 2...10 to the rows 1...9. Each result is replicated by using the command rep() and it's assigned to the new column diff.
solution 1
One way to that is with one simple loop:
(download mydata.csv)
a = read.table("mydata.csv",header=T,sep=";")
a$delta= NA
for(i in seq(1, nrow(a), by=2 )){
a[i,"delta"] = a[i+1,"delta"] = a[i+1,"log"] - a[i,"log"]
}
What is going on here is that the for loop iterates on every odd number (that's what the seq(...,by=2) does. So for the first, third, fifth, etc. row we assign to that row AND the following one the computed difference.
which returns:
> a
su match log delta
1 1 match 5.80 0.30
2 1 mismatch 6.10 0.30
3 2 match 6.09 -0.04
4 2 mismatch 6.05 -0.04
5 3 match 6.42 -0.12
6 3 mismatch 6.30 -0.12
7 4 match 6.20 -0.20
8 4 mismatch 6.00 -0.20
9 5 match 5.90 0.19
10 5 mismatch 6.09 0.19
solution 2
If you have a lot of data this approach can be slow. And generally R works better with another form of iterative functions which are the apply family.
The same code of above can be optimized like this:
a$delta = rep(
sapply(seq(1, nrow(a), by=2 ),
function(i){ a[i+1,"log"] - a[i,"log"] }
),
each=2)
Which gives the very same result as the first solution, should be faster, but also somewhat less intuitive.
solution 3
Finally it looks to me that you're trying to use a convoluted approach by using the long dataframe format, given your kind of data.
I'd reshape it to wide, and then operate more logically with separate columns, without the need of duplicate data.
Like this:
a = read.table("mydata.csv",header=T,sep=";")
a = reshape(a, idvar = "su", timevar = "match", direction = "wide")
#now creating what you want became a very simple thing:
a$delta = a[[3]]-a[[2]]
Which returns:
>a
su log.match log.mismatch delta
1 1 5.80 6.10 0.30
3 2 6.09 6.05 -0.04
5 3 6.42 6.30 -0.12
7 4 6.20 6.00 -0.20
9 5 5.90 6.09 0.19
The delta column contains the values you need. If you really need the long format for further analysis you can always go back with:
a= reshape(a, idvar = "su", timevar = "match", direction = "long")
#sort to original order:
a = a[with(a, order(su)), ]

What kind of algorithm is used to generate a square matrix?

I need generate a matrix and fill with numbers and inactive cells, but that the sum of each columns or rows are equal. I know the magic box and sudoku, but is different. Can you help me please? What kind algorithm I need use for generate this matrix?
E.g
X = 0 = block inactive
Matrix ( 4x4 )
0 8 4 X | 12
2 0 8 2 | 12
10 1 X 1 | 12
0 3 X 9 | 12
____________|
12 12 12 12
Other example:
Matrix ( 5x5 )
0 2 2 3 5 | 12
2 4 0 5 1 | 12
8 2 0 2 0 | 12
0 4 2 0 6 | 12
2 0 8 2 0 | 12
______________|
12 12 12 12 12
The result can be any other number, it is not always 12. Just as in Example I was easier to do for me. It's not be symmetrical.
Note: This is not magic box, also is not sudoku.
Conclusion:
1) I need build this box and fill with number and block inactive.
2) Always matrix is square(3x3, 4x4, 5x5, NxN, ...)
3) When I fill of space is not block, I can use number one, two or three digits.
4) The sum of all sides must be equal.
5) In the above example, X is block. Block mean not use for player.
6) you can inactive block can be 0, however does not affect the sum.
7) There is also no restriction on how many blocks or inactive will have no
8) To fill cells with numbers, this can be repeated if you want. There is not restriction.
9) The matrix is ​​always a square and may be of different dimensions. (2)
Thanks guys for your help. And sorry that the problem is incomplete and for my english is too bad, but that's all.
In terms of agorithms, I would approach it as a system of linear equations. You can put the box as a matrix of variables:
x11 x12 x13 x14
x21 x22 x23 x24
x31 x32 x33 x34
x41 x42 x43 x44
Then you would make the equations as:
row1 = row2 (x11 + x12 + x13 + x14 = x21 + x22 + x23 + x24)
row1 = row3 (...)
row1 = row4
row1 = col1
row1 = col2
row1 = col3
row1 = col4
For N = 4, you would have 16 variables and 7 equations, so you would have a solution with a number of degrees of freedom (at least 9, as pointed out by #JamesMcLeod, and exactly 9, as stated by #Chris), so you could generate every possible matrix satisfying the restrictions just giving values to every free parameter. In the resulting matrix, you could mark every cell with 0 as an inactive cell.
To do this however you would need a library or software package with the ability to solve systems of linear equations with degrees of freedom (several math software packages can do this, but right now only Maple comes to my mind).
PD: I've just read that numbers must have one, two or three digits (and be positive, too?). To address this, you could just "take care" when choosing the values for the free parameters once the system of equations is solved, or you could add inequalities to the problem like:
x11 < 1000
x11 >= 0 (if values must be positive)
x12 < 1000
(...)
But then it would be a linear programming problem. You may approach it like this too.
PD2: You can also make simple cases with diagonal matrices:
7 X X X
X 7 X X
X X 7 X
X X X 7
But I guess you already knew that...
Edit: Thanks James McLeod and Chris for your corrections.
do you fill the matrix with random numbers? You need a function that has an argument as 1 dimension vector which will verify if the sum of the row's elements is 12, then you can still use this function for columns(with a loop) into your main.

what is the algorithm for going around anti clockwise

I was able to make an algorithm for going around clockwise: 1 -> 2 -> 3 -> 4 -> 1 -> 2 -> 3 ...
It's like this:
(i % 4) + 1
Now I need to do the opposite thing: 4 -> 3 -> 2 -> 1 -> 4 -> 3 -> 2 ...
Can you please help me, this is making me mad. :D
Thanks!
Try the following formula for anti clockwise values
4-(i % 4)
How about
5 - ((i % 4) + 1)
seems to do the trick. May not be optimal but it works
Take a look at your "clockwise" series - you'll note the "counterclockwise" series is always five minus the corresponding clockwise value. Thus,
5 - ((i % 4) + 1)
should work. The parentheses may be omitted as well in most languages as % is typically performed before addition and subtraction.
I'm surprised it wasn't mentioned here, but there's no real reason to subtract anything (I personally think it's less readable that way) - an addition modulo can do the same -
(i + 3) % 4
In general -
(i + (N-1)) % N
Or for going back any arbitrary step m -
(i + (N-m)) % N

Resources