Mathematica list will not populate - wolfram-mathematica

NOTE: I am not a Mathematica programmer, but for a class I need to write expressions in it. I understand it is a functional language unlike C or Java.
I am trying to 'compare' (I use that for lack of a better term) the indexes or two irrational numbers. I then try to store whether or not they are equal, 1 and 0 respectively, in a list. Though, the comparison list is not populated (OUTPUT = "{}")
What is wrong with my logic in the for loop (aside from being non-functionally programed and inefficient)
piDigits = RealDigits[N[Pi, 15000000]]
rootDigits = RealDigits[N[Sqrt[2],15000000]]
comparisonList = List[]
For[i = 1, i < Length[Part[piDigits, 0]], i++,
If[Part[piDigits, i] == Part[rootDigits, i] ,
Append[comparisonList, 1], Append[comparisonList, 0]]]
comparisonList

Related

Make Return[] do its proper (C++) task

I saw that there are many threads about the Return[] function on this site. There is even a very good description of its behavior. But what happens if I'm really new to Mathematica?
Without further ado, I want to use this function:
getBinIndex[eta_, pt_, etalimits_, ptlimits_] :=
List[
For[i = 1, i < Length[etalimits], i++,
If[eta < etalimits[[i + 1]], Return[i]]],
For[i = 1, i < Length[ptlimits], i++,
If[pt < ptlimits[[i + 1]], Return[i]]]
];
As you can see, I am really new. I suppose there are 1 million ways of doing this in Mathematica but I have a C background and I feel the need to tell the computer everything. The function works. It returns a list with 2 variables which, after lots of testing, are OK. But it puts the results as the argument of two Return's: {Return[4],Return[5]} which I can't use as indexes for a...Table, for example. What do you need to do to get these Return[x] into x?
To give you an idea of how much a newb I am, I tried N[Return[i]].
Cheers,
Adrian
Catch[For[ .... If[ Throw[i] ] ]
Of course in mathematica you hardly ever need loops..
something like
Position[etalimits,ei_/;ei<eta&][[1,1]]
will do.
edit .. try this:
For[i = 1, i < Length[etalimits], i++,
If[eta < etalimits[[i + 1]], Return[i,CompoundExpression]]];,
Note the extra semicolon which makes the For[] loop a CompoundExpression. Personally I find this weird and wouldn't use it..

Enumerate a "map" variable

I have the following "map" variables:
permutation[100]=-2;
permutation[3]=-1;
permutation[19]=0;
permutation[-20]=1;
Is there a way to enumerate all of the values?
I don't care about enumeration order.
I mean something like this (not working code):
Do[i+=3,{i,permutation}]
I tell them "map" variables inspired from C++. What is the correct name for them, to found better search results?
This is "Meta Mathematica"
Definitions for a variable or a functions are stored internally and can be extracted using DownValues[]
so, if you want the set of "input values" for which permutation is defined use
Cases[DownValues[permutation], permutation[x_] :> x, \[Infinity]]
resulting with
{-20, 3, 19, 100}
yehuda
what you have done is basically define a function of discrete values. If you maintain a list of the values you can do this:
permutation[100] = -2;
permutation[3] = -1;
permutation[19] = 0;
permutation[-20] = 1;
vals = {100, 3, 19, -20}
use like this:
f /# permutation /# vals -> {f[-2], f[-1], f[0], f[1]}
or in a loop..
Do[ Print[permutation[vals[[i]]]], {i, Length[vals]}]
there are probably better ways to define your data in the first place..
here is a sometimes useful trick (only works for posative args though)
permutation = SparseArray[{}, {200}, Null]
permutation[[100]] = -2;
permutation[[3]] = -1;
permutation[[19]] = 0;
f /# Select[ permutation, ! (TrueQ[# == Null]) &]
out: {f[-1], f[0], f[-2]}
simplest though is to just make permutation a list:
permutation={}
AppendTo[permutation,{100,2}]
AppendTo[permutation,{3,-1}]
then do
f[#[[2]]]& /# permutation -> {f[2],f[-1]}

Translating from Maple to Mathematica

Sorry if this question doesn't fit the site well... I have been trying translate a bit of Maple-code into Mathematica. I don't know Maple at all but I do know some Mathematica. I really don't know what I am doing so I wonder if someone could help me just a bit:
b:= proc(n, s) local sn, m;
if n<1 then 1
else sn:= [s[], n]; m:= nops(sn);
`if` (m*(m-1)/2 = nops (({seq (seq (sn[i]-sn[j],
j=i+1..m), i=1..m-1)})), b(n-1, sn), 0) +b(n-1, s)
fi
end:
a:= proc(n) a(n):= b(n-1, [n]) +`if` (n=0, -1, a(n-1)) end:
seq(a(n), n=1..30);
I think I understand everything except
sn:= [s[], n];
but I'm not sure. Thanks in advance!
The indexing call s[] returns the sequence of the entries of s if s is a list or a set.
For s of type list (in particular) the call s[] behaves like the call op(s). (Note that this similarity in behavior is true for lists, sets, and sequences. But it's not true for all types.)
L:=[2,4,7]:
L[];
2, 4, 7
op(L);
2, 4, 7
[L[], 5];
[2, 4, 7, 5]
So [s[], n] takes list s and creates a new list. The new list, which gets assigned to sn, contains the entries of list s followed by n.

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.

Problem coming up with an array function

Let's say I have an increasing sequence of integers: seq = [1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 4 ... ] not guaranteed to have exactly the same number of each integer but guaranteed to be increasing by 1.
Is there a function F that can operate on this sequence whereby F(seq, x) would give me all 1's when an integer in the sequence equals x and all other integers would be 0.
For example:
t = [1, 1, 1, 1, 2, 2, 3, 3, 3, 4]
F(t, 2) = [0, 0, 0, 0, 1, 1, 0, 0, 0, 0]
EDIT: I probably should have made it more clear. Is there a solution where I can do some algebraic operations on the entire array to get the desired result, without iterating over it?
So, I'm wondering if I can do something like: F(t, x) = t op x ?
In Python (t is a numpy.array) it could be:
(t * -1) % x or something...
EDIT2: I found out that the identity function I(t[i] == x) is acceptable to use as an algebraic operation. Sorry, I did not know about identity functions.
There's a very simple solution to this that doesn't require most of the restrictions you place upon the domain. Just create a new array of the same size, loop through and test for equality between the element in the array and the value you want to compare against. When they're the same, set the corresponding element in the new array to 1. Otherwise, set it to 0. The actual implementation depends on the language you're working with, but should be fairly simple.
If we do take into account your domain, you can introduce a couple of optimisations. If you start with an array of zeroes, you only need to fill in the ones. You know you don't need to start checking until the (n - 1)th element, where n is the value you're comparing against, because there must be at least one of the numbers 1 to n in increasing order. If you don't have to start at 1, you can still start at (n - start). Similarly, if you haven't come across it at array[n - 1], you can jump n - array[n - 1] more elements. You can repeat this, skipping most of the elements, as much as you need to until you either hit the right value or the end of the list (if it's not in there at all).
After you finish dealing with the value you want, there's no need to check the rest of the array, as you know it'll always be increasing. So you can stop early too.
A simple method (with C# code) is to simply iterate over the sequence and test it, returning either 1 or 0.
foreach (int element in sequence)
if (element == myValue)
yield return 1;
else
yield return 0;
(Written using LINQ)
sequence.Select(elem => elem == myValue ? 1 : 0);
A dichotomy algorithm can quickly locate the range where t[x] = n making such a function of sub-linear complexity in time.
Are you asking for a readymade c++, java API or are you asking for an algorithm? Or is this homework question?
I see the simple algorithm for scanning the array from start to end and comparing with each. If equals then put as 1 else put as 0. Anyway to put the elements in the array you will have to access each element of the new array atleast one. So overall approach will be O(1).
You can certainly reduce the comparison by starting a binary search. Once you find the required number then simply go forward and backward searching for the same number.
Here is a java method which returns a new array.
public static int[] sequence(int[] seq, int number)
{
int[] newSequence = new int[seq.length];
for ( int index = 0; index < seq.length; index++ )
{
if ( seq[index] == number )
{
newSequence[index] = 1;
}
else
{
newSequence[index] = 0;
}
}
return newSequence;
}
I would initialize an array of zeroes, then do a binary search on the sequence to find the first element that fits your criteria, and only start setting 1's from there. As soon as you have a not equal condition, stop.
Here is a way to do it in O(log n)
>>> from bisect import bisect
>>> def f(t, n):
... i = bisect(t,n-1)
... j = bisect(t,n,lo=i) - i
... return [0]*i+[1]*j+[0]*(len(t)-j-i)
...
...
>>> t = [1, 1, 1, 1, 2, 2, 3, 3, 3, 4]
>>> print f(t, 2)
[0, 0, 0, 0, 1, 1, 0, 0, 0, 0]

Resources