Can it be implemented in Mathematica in CDF format? - wolfram-mathematica

Encouraged by the advertisement of the new Deployment & Connectivity features, I decided to use Mathematica 8 for developing a simple application to be shared with my colleagues. The purpose is to demonstrate user interface for our interactive method of multiobjective optimization. This interface is used for setting some pairwise coefficients for a set of criteria (which is not important in the context my question).
What is important is that I need to display a table containing input fields which interact with each other, and in particular can be dynamically replaced with non-interactive contents (e.g. text) during the interaction process.
After developing the application and deploying it to CDF I learned that it does not work in internet browsers (because I don’t use Manipulate function with its very limited capabilities). My application even doesn’t work correctly in the Mathematica player!
The very simplified version of my application is presented below. The question is following: can an interactive application like that (keeping in mind the “What is important” part) be implemented in Mathematica 8 in such a way that it can be shared with other people (mainly on the Windows platform) not having Mathematica installed? If not, could you suggest an alternative platform for implementing such kind of interactive application in an easiest way (Python? Java?).
Thank you in advance.
nCriteria = 5;
RatioControl[{i_, j_}] := Dynamic[
If[Ratio[i, j] === Null,
If[Ratio[j, i] === Null,
InputField[Dynamic#Ratio[i, j], Number, FieldSize -> 4],
N[1/Ratio[j, i]]
], Ratio[i, j]
]
];
ControlTable = Dynamic[
Grid[
Table[
If[i == j, Item["", Background -> GrayLevel[0.7]],
RatioControl[{i, j}]],
{i, nCriteria}, {j, nCriteria}
], Frame -> All
]
];
Do[Ratio[i, j] = Null, {i, nCriteria}, {j, nCriteria}];
ControlTable

This should work in your CFD.
DynamicModule[{}, Dynamic[Grid[
Table[If[i == j, Item["", Background -> GrayLevel[0.7]],
RatioControl[{i, j}]], {i, nCriteria}, {j, nCriteria}],
Frame -> All]],
Initialization :> (RatioControl[{i_, j_}] := Dynamic[
If[Ratio[i, j] === Null, If[Ratio[j, i] === Null,
InputField[Dynamic#Ratio[i, j], Number, FieldSize -> 4],
N[1/Ratio[j, i]]], Ratio[i, j]]];
nCriteria = 5;
Do[Ratio[i, j] = Null, {i, nCriteria}, {j, nCriteria}])]

Related

Trouble using position in wolfram-mathematica

Hi im coding a homework in mathematica about finding the probability of a program failing, make a plot and a table with the results however Im having trouble getting the last value of the table
Clear[bin1]
bin1[n_, p_, k_] :=
Module[{prob = (1 - p)^n, i},
Do[prob = (((n - i + 1)/i) (p/(1 - p))) prob, {i, k}]; prob]
distribution =
Table[bin1[50, #, k], {k, 0, 50}] & /# Range[0, .9, .1];
thats the probability calculator
prob = Max[Take[distribution, {#}]] & /# Range[1, 10] thats to take the first value of the table (its the porcentage of failiure)
position = # & /# Range[0, .9, .1](thats just for the third value)
max = Last[
Last[Position[distribution, Take[prob {#}] & /# Range[1, 10]]]]
thats the third value and where i have trouble its supossed to be tha maximum value but the prob{#} part doesnt work i have no idea why
The final table should be: TableForm[{position, prob, max}]
See the documentation for Module:
Module[{x,y,…},expr]
specifies that occurrences of the symbols x, y, … in expr should be treated as local.
When you say bin1[n_, p_, k_] := Module[{prob = …}], then prob is only defined inside the Module, and has no value outside.
You can see how this works by playing with it:
In[1]:= Module[{foo}, foo]
Out[1]= foo$185
Module renames variables inside its scope to have unique names not accessible outside.
You’ll probably need another function to compute prob, or set up bin1[] to compute both distribution and probability.

How to obtain values from a NMaximize in a For loop

I am using NMaximize to obtain values from an NDSolve function:
Flatten[NDSolve[{x''[t] == (F Cos[\[CapitalOmega] t] -
c x'[t] - (k + \[Delta]kb) x[t] + \[Delta]kb y[t])/m,
y''[t] == (-c y'[t] - (k + \[Delta]kb) y[t] + \[Delta]kb x[t])/m,
x'[0] == 0, y'[0] == 0, x[0] == 0, y[0] == 0}, {x[t], y[t]}, {t, 0, 10}]];
NMaximize[{Evaluate[y[t] /. s], 8 < t < 9}, t]
This is the case of a set of coupled, second order, ordinary differential equations (they were derived by a constant rotational speed gyroscope).
I need to obtain the maximum of the response function after the transient solution has faded and no longer influences the result.
I am trying to use a For loop to obtain the different maximums achieved for a range of "CapitalOmega", say 80 to 130 in steps of 1/2.
Currently I am getting the result in a form:
{a, {t -> b}}
How could This be placed on a list for all the values of "a" obtained from the For loop? This so they can be plotted using
ListLinePlot[]
If for each value of CapitalOmega you are getting some {a,{t->b}} from your NDSolve and you just want the list of 'a' values then
Table[First[NDSolve[...],{CapitalOmega,80,130,1/2}]
should do it. The First will extract the 'a' each time and using Table instead of For will put them in a list for you. If my example isn't exactly what your actual code is then you should still be able to use this idea to accomplish what you want.
Note: When I try to paste just your NDSolve[...] into Mathematica I get
NDSolve::ndnum: Encountered non-numerical value for a derivative at t==0.`.
which may be a real problem or may just be because of how you cut and pasted your posting.

Mathematica fast 2D binning algorithm

I am having some trouble developing a suitably fast binning algorithm in Mathematica. I have a large (~100k elements) data set of the form
T={{x1,y1,z1},{x2,y2,z2},....}
and I want to bin it into a 2D array of around 100x100 bins, with the bin value being given by the sum of the Z values that fall into each bin.
Currently I am iterating through each element of the table, using Select to pick out which bin it is supposed to be in based on lists of bin boundaries, and adding the z value to a list of values occupying that bin. At the end I map Total onto the list of bins, summing their contents (I do this because I sometimes want to do other things, like maximize).
I have tried using Gather and other such functions to do this but the above method was ridiculously faster, though perhaps I am using Gather poorly. Anyway It still takes a few minutes to do the sorting by my method and I feel like Mathematica can do better. Does anyone have a nice efficient algorithm handy?
Here is a method based on Szabolcs's post that is about about an order of magnitude faster.
data = RandomReal[5, {500000, 3}];
(*500k values*)
zvalues = data[[All, 3]];
epsilon = 1*^-10;(*prevent 101 index*)
(*rescale and round (x,y) coordinates to index pairs in the 1..100 range*)
indexes = 1 + Floor[(1 - epsilon) 100 Rescale[data[[All, {1, 2}]]]];
res2 = Module[{gb = GatherBy[Transpose[{indexes, zvalues}], First]},
SparseArray[
gb[[All, 1, 1]] ->
Total[gb[[All, All, 2]], {2}]]]; // AbsoluteTiming
Gives about {2.012217, Null}
AbsoluteTiming[
System`SetSystemOptions[
"SparseArrayOptions" -> {"TreatRepeatedEntries" -> 1}];
res3 = SparseArray[indexes -> zvalues];
System`SetSystemOptions[
"SparseArrayOptions" -> {"TreatRepeatedEntries" -> 0}];
]
Gives about {0.195228, Null}
res3 == res2
True
"TreatRepeatedEntries" -> 1 adds duplicate positions up.
I intend to do a rewrite of the code below because of Szabolcs' readability concerns. Until then, know that if your bins are regular, and you can use Round, Floor, or Ceiling (with a second argument) in place of Nearest, the code below will be much faster. On my system, it tests faster than the GatherBy solution also posted.
Assuming I understand your requirements, I propose:
data = RandomReal[100, {75, 3}];
bins = {0, 20, 40, 60, 80, 100};
Reap[
Sow[{#3, #2}, bins ~Nearest~ #] & ### data,
bins,
Reap[Sow[#, bins ~Nearest~ #2] & ### #2, bins, Tr##2 &][[2]] &
][[2]] ~Flatten~ 1 ~Total~ {3} // MatrixForm
Refactored:
f[bins_] := Reap[Sow[{##2}, bins ~Nearest~ #]& ### #, bins, #2][[2]] &
bin2D[data_, X_, Y_] := f[X][data, f[Y][#2, #2~Total~2 &] &] ~Flatten~ 1 ~Total~ {3}
Use:
bin2D[data, xbins, ybins]
Here's my approach:
data = RandomReal[5, {500000, 3}]; (* 500k values *)
zvalues = data[[All, 3]];
epsilon = 1*^-10; (* prevent 101 index *)
(* rescale and round (x,y) coordinates to index pairs in the 1..100 range *)
indexes = 1 + Floor[(1 - epsilon) 100 Rescale[data[[All, {1, 2}]]]];
(* approach 1: create bin-matrix first, then fill up elements by adding zvalues *)
res1 = Module[
{result = ConstantArray[0, {100, 100}]},
Do[
AddTo[result[[##]], zvalues[[i]]] & ## indexes[[i]],
{i, Length[indexes]}
];
result
]; // Timing
(* approach 2: gather zvalues by indexes, add them up, convert them to a matrix *)
res2 = Module[{gb = GatherBy[Transpose[{indexes, zvalues}], First]},
SparseArray[gb[[All, 1, 1]] -> (Total /# gb[[All, All, 2]])]
]; // Timing
res1 == res2
These two approaches (res1 & res2) can handle 100k and 200k elements per second, respectively, on this machine. Is this sufficiently fast, or do you need to run this whole program in a loop?
Here's my approach using the function SelectEquivalents defined in What is in your Mathematica tool bag? which is perfect for a problem like this one.
data = RandomReal[100, {75, 3}];
bins = Range[0, 100, 20];
binMiddles = (Most#bins + Rest#bins)/2;
nearest = Nearest[binMiddles];
SelectEquivalents[
data
,
TagElement -> ({First#nearest[#[[1]]], First#nearest[#[[2]]]} &)
,
TransformElement -> (#[[3]] &)
,
TransformResults -> (Total[#2] &)
,
TagPattern -> Flatten[Outer[List, binMiddles, binMiddles], 1]
,
FinalFunction -> (Partition[Flatten[# /. {} -> 0], Length[binMiddles]] &)
]
If you would want to group according to more than two dimensions you could use in FinalFunction this function to give to the list result the desired dimension (I don't remember where I found it).
InverseFlatten[l_,dimensions_]:= Fold[Partition[#, #2] &, l, Most[Reverse[dimensions]]];

Identify important minima and maxima in time-series w/ Mathematica

I need a way to identify local minima and maxima in time series data with Mathematica. This seems like it should be an easy thing to do, but it gets tricky. I posted this on the MathForum, but thought I might get some additional eyes on it here.
You can find a paper that discusses the problem at: http://www.cs.cmu.edu/~eugene/research/full/compress-series.pdf
I've tried this so far…
Get and format some data:
data = FinancialData["SPY", {"May 1, 2006", "Jan. 21, 2011"}][[All, 2]];
data = data/First#data;
data = Transpose[{Range[Length#data], data}];
Define 2 functions:
First method:
findMinimaMaxima[data_, window_] := With[{k = window},
data[[k + Flatten#Position[Partition[data[[All, 2]], 2 k + 1, 1], x_List /; x[[k + 1]] < Min[Delete[x, k + 1]] || x[[k + 1]] > Max[Delete[x, k + 1]]]]]]
Now another approach, although not as flexible:
findMinimaMaxima2[data_] := data[[Accumulate#(Length[#] & /# Split[Prepend[Sign[Rest#data[[All, 2]] - Most#data[[All, 2]]], 0]])]]
Look at what each the functions does. First findMinimaMaxima2[]:
minmax = findMinimaMaxima2[data];
{Length#data, Length#minmax}
ListLinePlot#minmax
This selects all minima and maxima and results (in this instance) in about a 49% data compression, but it doesn't have the flexibility of expanding the window.
This other method does. A window of 2, yields fewer and arguably more important extrema:
minmax2 = findMinimaMaxima[data, 2];
{Length#data, Length#minmax2}
ListLinePlot#minmax2
But look at what happens when we expand the window to 60:
minmax2 = findMinimaMaxima[data, 60];
ListLinePlot[{data, minmax2}]
Some of the minima and maxima no longer alternate.
Applying findMinimaMaxima2[] to the output of findMinimaMaxima[] gives a workaround...
minmax3 = findMinimaMaxima2[minmax2];
ListLinePlot[{data, minmax2, minmax3}]
, but this seems like a clumsy way to address the problem.
So, the idea of using a fixed window to look left and right doesn't quite do everything one would like. I began thinking about an alternative that could use a range value R (e.g. a percent move up or down) that the function would need to meet or exceed to set the next minima or maxima. Here's my first try:
findMinimaMaxima3[data_, R_] := Module[{d, n, positions},
d = data[[All, 2]];
n = Transpose[{data[[All, 1]], Rest#FoldList[If[(#2 <= #1 + #1*R && #2 >= #1) || (#2 >= #1 - #1* R && #2 <= #1), #1, #2] &, d[[1]], d]}];
n = Sign[Rest#n[[All, 2]] - Most#n[[All, 2]]];
positions = Flatten#Rest[Most[Position[n, Except[0]]]];
data[[positions]]
]
minmax4 = findMinimaMaxima3[data, 0.1];
ListLinePlot[{data, minmax4}]
This too benefits from post processing with findMinimaMaxima2[]
ListLinePlot[{data, findMinimaMaxima2[minmax4]}]
But if you look closely, you see that it misses the extremes if they go beyond the R value in several positions - including the chart's absolute minimum and maximum as well as along the big moves up and down. Changing the R value shows how it misses the top and bottoms even more:
minmax4 = findMinimaMaxima3[data, 0.15];
ListLinePlot[{data, minmax4}]
So, I need to reconsider. Anyone can look at a plot of the data and easily identify the important minima and maxima. It seems harder to get an algorithm to do it. A window and/or an R value seem important to the solution, but neither on their own seems enough (at least not in the approaches above).
Can anyone extend any of the approaches shown or suggest an alternative to identifying the important minima and maxima?
Happy to forward a notebook with all of this code and discussion in it. Let me know if anyone needs it.
Thank you,
Jagra
I suggest to use an iterative approach. The following functions are taken from this post, and while they can be written more concisely without Compile, they'll do the job:
localMinPositionsC =
Compile[{{pts, _Real, 1}},
Module[{result = Table[0, {Length[pts]}], i = 1, ctr = 0},
For[i = 2, i < Length[pts], i++,
If[pts[[i - 1]] > pts[[i]] && pts[[i + 1]] > pts[[i]],
result[[++ctr]] = i]];
Take[result, ctr]]];
localMaxPositionsC =
Compile[{{pts, _Real, 1}},
Module[{result = Table[0, {Length[pts]}], i = 1, ctr = 0},
For[i = 2, i < Length[pts], i++,
If[pts[[i - 1]] < pts[[i]] && pts[[i + 1]] < pts[[i]],
result[[++ctr]] = i]];
Take[result, ctr]]];
Here is your data plot:
dplot = ListLinePlot[data]
Here we plot the mins, which are obtained after 3 iterations:
mins = ListPlot[Nest[#[[localMinPositionsC[#[[All, 2]]]]] &, data, 3],
PlotStyle -> Directive[PointSize[0.015], Red]]
The same for maxima:
maxs = ListPlot[Nest[#[[localMaxPositionsC[#[[All, 2]]]]] &, data, 3],
PlotStyle -> Directive[PointSize[0.015], Green]]
And the resulting plot:
Show[{dplot, mins, maxs}]
You may vary the number of iterations, to get more coarse-grained or finer minima/maxima.
Edit:
actually, I just noticed that a couple of points were still missed by this method, both for the
minima and maxima. So, I suggest it as a starting point, not as a complete solution. Perhaps, you
could analyze minima/maxima, coming from different iterations, and sometimes include those from a "previous", more fine-grained one. Also, the only "physical reason" that this kind of works, is that the nature of the financial data appears to be fractal-like, with several distinctly different scales. Each iteration in the above Nest-s targets a particular scale. This would not work so well for an arbitrary signal.

Circular/Angular slider

A recent SO question reminded me of some code I tried to write a while back. The aim is to make a CircularSlider[] object that can be used for angle-like variables in dynamic objects.
The framework for my solution (below) comes from the ValueThumbSlider[] defined in the Advanced Manipulate Functionality tutorial. The main difference is that in ValueThumbSlider[] the value of the slider and the position of the LocatorPlane[] are the same thing, whilst in my CircularSlider[] they are not - and this leads to problems.
The first problem is that moving the Locator will not change the slider value. This is fixed by using the 2nd argument in the Dynamic: (x = #/Abs[Complex ## #]) &.
This in turn leads to the problem that if you externally set the value of the slider (t) from outside, it will immediately revert to its previous value. This is fixed by keeping the old value (t0) and comparing to t. If they don't match then it's assumed that t has changed and so the Locator position x is updated to its new position.
CircularSlider[t_] := CircularSlider[t, {0, 1}];
CircularSlider[Dynamic[t_], {min_, max_}] /; max > min :=
With[{d = (max - min)/(2. Pi)},
DynamicModule[{td = t/d, x, t0}, x = {Cos[td], Sin[td]};
LocatorPane[
Dynamic[If[!NumberQ[t], t = min; x = {Cos[td], Sin[td]}];
If[t != t0, t0 = t; x = {Cos[td], Sin[td]}];
t = Mod[Arg[Complex ## x] d, max, min]; t0 = t;
x, (x = #/Abs[Complex ## #]) &],
Graphics[{AbsoluteThickness[1.5], Circle[],
Dynamic[{Text[NumberForm[t, {3, 2}], {0, 0}]}]}],
ImageSize -> Small]]]
So my question is: can someone make this work with out the above kludges?
As for problem#1, I wouldn't consider the use of the second argument to Dynamic as a kludge -- that is what the second argument is for. Therefore, I don't have an alternative solution for that one.
Problem #2 can be avoided if you refrain from assigning t in the first argument to Dynamic.
With this in mind, here is another implementation:
CircularSlider2[Dynamic[t_], r:{min_, max_}:{0, 1}] :=
DynamicModule[{scale, toXY, fromXY},
scale = (max - min) / (2. Pi);
toXY[a_?NumberQ] := Through#{Cos, Sin}[a / scale];
toXY[a_] := {1, 0};
fromXY[{x_, y_}] := Mod[Arg[x + I y] scale, max, min];
LocatorPane[
Dynamic[toXY[t], (t = fromXY[#])&],
Graphics[{
AbsoluteThickness[1.5], Circle[],
Dynamic[{Text[NumberForm[t, {3,2}], {0, 0}]}]
}],
ImageSize -> Small
]
]
The only material difference between this version and the original version is that the first argument to Dynamic is an expresssion that is free of side-effects.
Edit
I just stumbled across this undocumented experimental feature in Mathematica 8:
DynamicModule[{x = RandomReal[{0, 50}]},
{Experimental`AngularSlider[Dynamic#x], Dynamic#x}
]

Resources