Group Abstract Group Abstract

Message Boards Message Boards

2
|
7.5K Views
|
5 Replies
|
9 Total Likes
View groups...
Share
Share this post:

Find real numbers closest to a multiple of 500 in a list?

Posted 9 years ago

I have a data file (see attached), which has two columns. The first is a frequency in MHz, and the second a phase in degrees. There are 1601 data points - the frequency spans 50 MHz to 7000 MHz, in steps of 4.34375 MHz.

I'd like to extract some of this data to put in a document, but I don't want to put all 1601 points. What I'd like to do is to find those data points that have a frequency nearest to a non-negative integer multiple of 500 MHz, (i.e. 0, 500, 1000, 1500, 2000, 2500 ...7000 MHz) and output only them. There's no data at 0 MHz, nor 500, nor 1000, but I want to find the closest to those. So I want the points

50.,0.21774563818642534  
501.75,0.26184339842516735 
1001.28125,0.5089995355033423 
1500.8125,0.5958289355437785
2000.34375,0.847843737588093
2499.875,0.9325320400864996
2999.40625,1.4433401865247077
.... 
7000.,2.1843935555882155

Any ideas?

Attachments:
POSTED BY: David Kirkby
5 Replies

Using a Do loop should be avoided in the answer of Paul, and Nearest is not used in a smart way. The answer of Joel has a similar problem as multiple datapoints could be selected; it depends on the factor 0.1 and 0.9 (ok for this test-data, but not a general solution). A faster/better way is as follows:

SetDirectory[NotebookDirectory[]];
data = Import["frequency-and-phase-data.csv"];
d = 500   (*the displacement *)
find = Range[Floor[Min[data[[All, 1]]], \[Delta]], Ceiling[Max[data[[All, 1]]], \[Delta]], \[Delta]] (*the points you look for*)
nf = Nearest[#[[1]] -> # & /@ data] (* make optimised nearest function*)
selected = First@*nf /@ find (* find for each point *)

{{50., 0.217746}, {501.75, 0.261843}, {1001.28, 0.509}, {1500.81, 
  0.595829}, {2000.34, 0.847844}, {2499.88, 0.932532}, {2999.41, 
  1.44334}, {3498.94, 1.67507}, {3998.47, 1.95012}, {4498., 
  2.02858}, {5001.88, 2.22979}, {5501.41, 2.45856}, {6000.94, 
  2.42086}, {6500.47, 2.26449}, {7000., 2.18439}}

You might have to interchange Floor and Ceiling, depending on how you want to handle the 'ends'.

POSTED BY: Sander Huisman
Posted 9 years ago

This would work, but first I opened the csv file with excel and saved it as an xlsx file. and the file is where MMa first looks for files.

data = Flatten[Import["frequency-and-phase-data.xlsx", "Data"], 1];
list = {}; Do[x = FromDigits[Nearest[data[[All, 1]], 500 n]]; 
 AppendTo[list, Cases[data, {a_, b_} /; a == x]], {n, 1, 
  14}]; Column[list]

giving

{{501.75,0.261843}}
{{1001.28,0.509}}
{{1500.81,0.595829}}
{{2000.34,0.847844}}
{{2499.88,0.932532}}
{{2999.41,1.44334}}
{{3498.94,1.67507}}
{{3998.47,1.95012}}
{{4498.,2.02858}}
{{5001.88,2.22979}}
{{5501.41,2.45856}}
{{6000.94,2.42086}}
{{6500.47,2.26449}}
{{7000.,2.18439}}

Change the 500 to 50 and the range in {n, 1, 14} to {n, 1, 140} for more points

Paul.

POSTED BY: Paul Cleary

First, look at the help of Nearest, second definition:

Nearest[{Subscript[elem, 1]->Subscript[v, 1],Subscript[elem, 2]->Subscript[v, 2],[Ellipsis]},x] gives the Subscript[v, i] corresponding to the Subscript[elem, i] to which x is nearest.

Second, I have no idea how you got a Hold to be honest.

First@*nf 

is the same as (in outcome)

First[nf[#]]&

Basically applying first the nearest function, then taking the First, but it works as a single function.

First@nf /@ 

does not do what you want:

f@g /@ {1, 2, 3, 4}
f@*g /@ {1, 2, 3, 4}

gives:

{f[g][1], f[g][2], f[g][3], f[g][4]}

{f[g[1]], f[g[2]], f[g[3]], f[g[4]]}

Note that in the first example f is applied to g, not g[1] ! It has to do with precedence(order, ranking) of the operators.

POSTED BY: Sander Huisman
Posted 9 years ago

Sir,

Thank you for your reply.

I now understand the use of Nearest better.

In analyzing your solution I noticed two items that I hope you can comment on:

  1. The use of the #[[1]] -> # in Nearest[#[[1]] -> # & /@ data].

    I was unaware that you could use a Rule to transform the output of an function as the input to function.

  2. The use of @* in First@*nf /@ find to function like ReleaseHold. Again, I was unaware of the use of @* to act as a ReleaseHold in this context. Why does using First in this manner result in the output having the evaluation being held? eg.

        First@nf /@ find
    
        {Hold[Nearest[{50.->{50.,0.217746},54.3438->{54.3438,0.53045},58.6875->{58.6875,0.561783},63.0313->{63.0313,0.336275},67.375->{67.375,0.368827},71.7188->{71.7188,0.417978},76.0625->{76.0625,0.450648},80.4063->{80.4063,0.442057},84.75->{84.75,0.423945},89.0938->{89.0938,0.514353},93.4375->{93.4375,0.415191},97.7813->{97.7813,0.468367},102.125->{102.125,0.450253},106.469->{106.469,0.333008},110.813->{110.813,0.431593},115.156->{115.156,0.395657},119.5->{119.5,0.37876},123.844->{123.844,0.246633},128.188->{128.188,0.376706},132.531->{132.531,0.401067},136.875->{136.875,0.557509},141.219->{141.219,0.282309},145.563->{145.563,0.25467},149.906->{149.906,0.464329},154.25->{154.25,0.321209},158.594->{158.594,0.401958},162.938->{162.938,0.278126},167.281->{167.281,0.281734},171.625->{171.625,0.182552}}]][50],
    
`Flatten /@ nf /@ find` (although incorrect in this context) does
        not have this effect.         

I don't mean to turn this thread into a Mathematica tutorial, but as someone who is still uncovering the subtle nuances of Mathematica, your insight is greatly appreciated.

POSTED BY: Joel Gilly
Posted 9 years ago

The "Select" function with a criteria is your friend in this case. The creation of a suitable criteria function would be the complicated part..

Using data supplied from your other post, this is something congruent to your query...

Select[thedata, (FractionalPart[IntegerPart[#[[1]]]/50] < 
     0.1) || (FractionalPart[IntegerPart[#[[1]]]/50] > 0.9) &] 

As mentioned above, you will need to tweak the criteria function to meet your specific application.

The "Nearest" function (see the online documentation) might also be applicable, but I am unfamiliar with it's use. I do not know how you would construct a criteria to narrow your results from "Nearest"...

POSTED BY: Joel Gilly
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard