Group Abstract Group Abstract

Message Boards Message Boards

2
|
8.2K 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 10 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

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 10 years ago
POSTED BY: Joel Gilly

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 10 years ago
POSTED BY: Joel Gilly
Posted 10 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
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard