Find defined variables and use them in Dynamic PopupMenu in mathematica - list

I'm working with Mathematica,
I begin by importing the data from some CSV files, and I store them under some variable names.
For the moment let's assume we use:
sample1 = Sort[RandomReal[{0, 10}, {10, 2}]];
sample2 = Sort[RandomReal[{0, 10}, {10, 2}]];
sample3 = Sort[RandomReal[{0, 10}, {10, 2}]];
So, I want to do some calculations on the data individually,
I was thinking of using a PopupMenu by "recalling" the defined variables and then I could do a linear fit and display both the data and the linear fit, and also find the highest value:
variables = Names["Global`*"];
PopupMenu[Dynamic[x], variables]
data=Dynamic[x];
lm = LinearModelFit[data, x, x];
Show[ListLinePlot[data, PlotRange-> All],
Plot[lm[x], {x, 0, data[[Length[data], 1]]}]]
Peak = Max[data[[All, 2]]]
But the problem is that when i recall the variables, Mathematica only brings them as names and not the actual data list.
For the moment I'm trying also to store different calculations on a bigger list that would go on storing the values for the calculations:
Data = {};
(This bit would be outside, with the data importing probably, just to define the list)
AppendTo[Data, {Normal[lm], Peak}]
I'm also trying to store the name of the set that's selected, so that's another challenge... Would anyone know how could I solve this issue?
I do realize that it's a pretty specific question (sorry!), but it could be used for other things too! I think...
Thanks!

Related

If x is y then z, else x without repeating x in Google Sheets

In a cell, is it possible to do if(x=y, z, x) without having to repeat x in the value_if_false argument? Whether there is a way of using if() to make this work or another function doesn't matter, and there isn't a specific formula I'm struggling with as I come across this blocker quite often (hence posting).
To help illustrate the need, if we take x as a complex or more advanced formula, such as
ARRAYFORMULA(IF(E$6:Q$6 < EoMONTH($P$4,0), "Not Active", IF(E$6:Q$6<$Q$4 + ISBLANK($Q$4) > 0,
COUNTIF({'Data'!$B$3:$B&'Data'!$I$3:$I&'Data'!$K$3:$K},$B$4&$C9&E$6:Q$6), "Not Active")))
and I wanted to put an if statement in there that changed the result only if a condition was true, the formula would more than double in size due to having to reference x twice:
=ARRAYFORMULA(IF(IF(E$6:Q$6 < EoMONTH($P$4,0), "Not Active", IF(E$6:Q$6<$Q$4 + ISBLANK($Q$4) > 0,
COUNTIF({'Data'!$B$3:$B&'Data'!$I$3:$I&'Data'!$K$3:$K},$B$4&$C9&E$6:Q$6), "Not Active"))) = 0, "No data", IF(E$6:Q$6 < EoMONTH($P$4,0), "Not Active", IF(E$6:Q$6<$Q$4 + ISBLANK($Q$4) > 0,
COUNTIF({'Data'!$B$3:$B&'Data'!$I$3:$I&'Data'!$K$3:$K},$B$4&$C9&E$6:Q$6), "Not Active"))))
This is just an example (the code is irrelevant), I'm trying to keep my formulas neat, tidy and efficient so that handing off to others is easier. Then I'm also mindful that it is calculating the same complex formula twice, which would probably slow the spreadsheet down especially when iterated throughout a spreadsheet.
Interested to hear the community thoughts and suggestions on this, hopefully I was clear in explaining it. :)
The only simple way to achieve this would be with the use of helper columns. They don't need to be in the same sheet as your main equation, but they do need to be within that same spreadsheet as a whole (ie you could have a sheet named "calc" that's specifically used to calculate intermediate steps and set "variables" by referencing those cells).
The only other option (which gets a bit complicated) is to create a custom function within Google Apps Script. For example, if you wanted to calculate (B1*A4)/C5 in multiple places, you could create a custom function like this:
/**
* Returns a calculation using cells A4, B1, and C5.
* #return A calculation using cells A4, B1, and C5.
* #customfunction
*/
function x() {
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('MainSheet');
var val1 = ss.getRange('B1').getValue();
var val2 = ss.getRange('A4').getValue();
var val3 = ss.getRange('C5').getValue();
return (val1*val2)/val3;
}
Then in your sheet, you could use this within a formula like this:
=if(A1="yes", x(), "no")
This custom function could obviously be altered to fit one's needs (ex taking in arguments to define the cells that the calculations should be done on instead of hard coding them, etc).
Other than this, there is currently no way to define variables within a formula itself.
This is possible to a certain extent, using TEXT's Meta Instructions, if you're using numbers and simple math conditions.
x
y
z
output
10
10
5
10
=TEXT(A3,"[="&B3&"]0;"&C3&"")
x
y
z
output
11
10
5
5
As long as your complex formula returns a number for x(or the output can be coerced to a number), this should be possible and it avoids repetition.
I agree, I would love if there was like a DECODE or NVL type function you could use so that you didn't need to repeat the original statement multiple times.
However, in many cases, when I encounter this, I can often reference another cell. Not in the way that has been suggested already, where the formula exists in another cell, but rather that the decision to perform the formula is based on another cell.
For example, using your values, lets assume the formula ((if(x=y, z, x)) only gets calculated when column 'w' is populated. Maybe column 'w' is a key component of the formula. Then you can write the formula as: if(w="",z,x). It's not exactly the same as testing the answer to the equation first and doesn't work in all situations, but in many cases I can find another field that's of key relevance to the formula that lets me get around this.

Plotting 2D lattice data from c++ in Mathematica

I have a (probably stupid) question:
How can I plot D-lattice data generated by a c++ program in mathematica (9)?
(I'd think intuitively that this can not be too hard but with google, stackoverflow etc. I could not find any solution)
What output format is best for this?
Which mathematica command is best?
At the moment I am trying to give out the data in columns where each row is of the form:
xcoordinate ycoordinate value
I found out that one could in principle solve this by using MatrixPlot[] but for this one would have to provide the data in a matrix form which is incompatible with most other plotting programs so I want to avoid this if possible.
I'm new to StackOverflow and a little bit worried about the requirements for answers. I did my best:
From the facts given in the question, I can't see why not simply use ListPlot3D? You do not need any particular order in the dataset, Mathematica will try to sort your data.
First, you can export your C++ data into a file of the form
x1 y1 value1
x2 y2 value2
x3 y3 value3
...
A file of this format can be imported using
Import["path/to/file.txt", "Table"]
You will then have a matrix like in the following example:
d1 = Flatten[Table[{x, y, Cos[Sqrt[x^2 + y^2]]}, {x, 0, 6, 0.2}, {y, 0, 6, 0.2}], 1];
d2 = RandomSample[d1]
ListPlot3D[d1]
ListPlot3D[d2]
d1 will be a flat list of {x,y,z}
d2 will be the same list in shuffled form
Both will yield the same nice plot of a wave originating in {0,0,1}
As far as I can tell, ListPlot3D is available since Mathematica 8.

C++ Undo Command / Reverse to previous state

I have a grid of randomly generated numbers of size gameSize (user input) which is contained within a vector of vectors. The user can enter two co-ordinates (x, y) so that it changes a number within the grid to a predefined value, which is "0".
So for example the user enters, X:0 Y:0 and:
{9, 7, 9}
{9, 6, 8}
{5, 1, 4}
becomes:
{0, 7, 9} <-- Changes position 0,0 to 0 (the predefined value)
{9, 6, 8}
{5, 1, 4}
I'm trying to figure out how to add an "undo" feature in which the user is prompted if they want to undo their selection or not, and if Yes then reverse the selection so that position 0,0 changes back to the original value (which is the value 9 in this example). How can I implement this? I understand I need to somehow record a previous grid state but have no clue how.
If you only want to be able to "undo" the last change, then you could simply make a copy, a backup of sorts, of the state before doing the change. Then if the user wants to "undo" the change then copy from the backup into the actual data.
For more levels of undo you could have a stack of copies.
If the data is large, then instead of copying the data for every change just store a copy of the actual change instead. Then when the user wants to "undo" you do the opposite of the change.
Example: If the user want to modify coordinates X,Y by Z, then store X, Y and Z. Then when doing undo you modify X,Y with -Z.
In object oriented languages you often find that people will use the command pattern to implement undo systems. Some people might say it's overkill but it is really quite flexible and doesn't take much boiler plate to get started.
The general idea is that you create an interface, with the methods execute() and undo(). You then you can create a whole slew of other classes that implement that interface and that know how do specific actions (e.g., in your example change position) and how to undo them. You then just need to keep track of commands that you have executed by putting them on a stack, and when you need to undo just pop them from the stack and call undo().
Here is a good resource for learning about the command pattern and design patterns in general.

Writing two variable in a root file in RootFramework

I am new in root framework. I want to draw a graph for example; x vs. y graph. These values are related each other in a for loop.I get x values and y values for each x value. However, I could not save these variables in the same root file to draw a x vs. y graph, I could not find how can I do, because when I use TBrowser and use Draw option I get only a vs. bin graph.
Besides, I try to Fill option but it is needed a histogram, I guess I do not want to get histogram. I search Root Support, but I could not find a result for that there, also here.
Is there any suggestion to plot a graph with these two variables? Also, how can I save these variables in the same file?
Thank you!
Have you tried using TGraph class?
If you store x and y in some sort of array you can easily do something like this:
TGraph* graph=new TGraph(n,x,y); //where n is size of x and y arrays
TCanvas *c1 = new TCanvas("c1","",0,0,600,600);
graph->Draw("AP");
c1->Print("Graph.pdf"); //you can use different file format in output
That should create a pdf file with your graph. For saving your data you could use TNtuple or TTree. They have separate branches for each variable and the variable values are passed by giving the adress of variable in your program to the branch. Or you can just save it in the text file
TGraph
TCanvas

Splitting a list based on another list values in Mathematica

In Mathematica I have a list of point coordinates
size = 50;
points = Table[{RandomInteger[{0, size}], RandomInteger[{0, size}]}, {i, 1, n}];
and a list of cluster indices these points belong to
clusterIndices = {1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1};
what is the easiest way to split the points into two separate lists based on the clusterIndices values?
EDIT:
The solution I came up with:
pointIndices =
Map[#[[2]] &,
GatherBy[MapIndexed[{#1, #2[[1]]} &, clusterIndices], First],
{2}];
pointsByCluster = Map[Part[points, #] &, pointIndices];
It there a better way to do this?
As #High Performance Mark and #Nicholas Wilson said, I'd start with combining the two lists together via Transpose or Thread. In this case,
In[1]:= Transpose[{clusterIndices, points}]==Thread[{clusterIndices, points}]
Out[1]:= True
At one point, I looked at which was faster, and I think Thread is marginally faster. But, it only really matters when you are using very long lists.
#High Performance Mark makes a good point in suggesting Select. But, it would only allow you to pull a single cluster out at a time. The code for selecting cluster 1 is as follows:
Select[Transpose[{clusterIndices, points}], #[[1]]==1& ][[All, All, 2]]
Since you seem to want to generate all clusters, I'd suggest doing the following:
GatherBy[Transpose[{clusterIndices, points}], #[[1]]& ][[All, All, 2]]
which has the advantage of being a one liner and the only tricky part was in selecting the correct Part of the resulting list. The trick in determining how many All terms are necessary is to note that
Transpose[{clusterIndices, points}][[All,2]]
is required to get the points back out of the transposed list. But, the "clustered" list has one additional level, hence the second All.
It should be noted that the second parameter in GatherBy is a function that accepts one parameter, and it can be interchanged with any function you wish to use. As such, it is very useful. However, if you'd like to transform your data as your gathering it, I'd look at Reap and Sow.
Edit: Reap and Sow are somewhat under used, and fairly powerful. They're somewhat confusing to use, but I suspect GatherBy is implemented using them internally. For instance,
Reap[ Sow[#[[2]], #[[1]] ]& /# Transpose[{clusterIndices, points}], _, #2& ]
does the same thing as my previous code without the hassle of stripping off the indices from the points. Essentially, Sow tags each point with its index, then Reap gathers all of the tags (_ for the 2nd parameter) and outputs only the points. Personally, I use this instead of GatherBy, and I've encoded it into a function which I load, as follows:
SelectEquivalents[x_List,f_:Identity, g_:Identity, h_:(#2&)]:=
Reap[Sow[g[#],{f[#]}]&/#x, _, h][[2]];
Note: this code is a modified form of what was in the help files in 5.x. But, the 6.0 and 7.0 help files removed a lot of the useful examples, and this was one of them.
Here's a succinct way to do this using the new SplitBy function in version 7.0 that should be pretty fast:
SplitBy[Transpose[{points, clusterIndices}], Last][[All, All, 1]]
If you aren't using 7.0, you can implement this as:
Split[Transpose[{points, clusterIndices}], Last[#]==Last[#2]& ][[All, All, 1]]
Update
Sorry, I didn't see that you only wanted two groups, which I think of as clustering, not splitting. Here's some code for that:
FindClusters[Thread[Rule[clusterIndices, points]]]
How about this?
points[[
Flatten[Position[clusterIndices, #]]
]] & /#
Union[clusterIndices]
I don't know about 'better', but the more usual way in functional languages would not be to add indices to label each element (your MapIndexed) but instead to just run along each list:
Map[#1[[2]] &,
Sort[GatherBy[
Thread[ {#1, #2} &[clusterIndices, points]],
#1[[1]] &], #1[[1]][[1]] < #2[[1]][[1]] &], {2}]
Most people brought up in Lisp/ML/etc will write the Thread function out instantly is the way to implement the zip ideas from those languages.
I added in the Sort because it looks like your implementation will run into trouble if clusterIndices = {2[...,2],1,...}. On the other hand, I would still need to add in a line to fix the problem that if clusterIndices has a 3 but no 2, the output indices will be wrong. It is not clear from your fragment how you are intending to retrieve things though.
I reckon you will find list processing much easier if you refresh yourself with a hobby project like building a simple CAS in a language like Haskell where the syntax is so much more suited to functional list processing than Mathematica.
If I think of something simpler I will add to the post.
Map[#[[1]] &, GatherBy[Thread[{points, clusterIndices}], #[[2]] &], {2}]
My first step would be to execute
Transpose[{clusterIndices, points}]
and my next step would depend on what you want to do with that; Select comes to mind.