I should have been more descriptive in previous response.
The ability to find the peaks and valleys of a sine wave using JMP is not one of JMP's built in analyses. However, by using JMP's Scripting Language(JSL) a script can be used to get the information you need.
The first thing I needed to start working on a solution to your question was a sample data table. JMP provides in it's installation however, I am not aware of any of them that provides the data values for a sine wave similar to the sine wave you provided in your initial question. I therefore had to create my own sample data table. The first part of my script does nothing more than create a sample data table.
Names Default To Here( 1 );
dt = New Table( "sine", New Column( "x" ), New Column( "y" ) );
For( k = 1, k <= 10, k++,
yfudgepos = Random Uniform( 0, .2 );
yfudgeneg = Random Uniform( 0, .2 );
For( x = 0, x <= 360, x++,
dt << add rows( 1 );
y = Sin( x / 180 * Pi() );
:x[Row()] = x + ((k - 1) * 360);
If( y < -1 * yfudgeneg,
:y[Row()] = y + yfudgeneg
);
If( y > yfudgepos,
:y[Row()] = y - yfudgePos
);
);
);
dt << select where(ismissing(:y));
dt << delete rows;Th
This part of the script create the sample data table. It is not a perfect sine wave data table.
I wanted the produced sine wave to have some variability for each wave. To accomplish this, the code adjusts the wave each time it goes above or below the mid of the wave. .The end result is a wave that has different maximum high points, and different minimum values for each wave. The end resulting data table has that variability, but it also creates a little step in the wave form. While the sample data table isn't perfect, it is good enough to use.
Here is the part of the script that produces the data for the above wave.
Names Default To Here( 1 );
dt = New Table( "sine", New Column( "x" ), New Column( "y" ) );
For( k = 1, k <= 10, k++,
yfudgepos = Random Uniform( 0, .2 );
yfudgeneg = Random Uniform( 0, .2 );
For( x = 0, x <= 360, x++,
dt << add rows( 1 );
y = Sin( x / 180 * Pi() );
:x[Row()] = x + ((k - 1) * 360);
If( y < -1 * yfudgeneg,
:y[Row()] = y + yfudgeneg
);
If( y > yfudgepos,
:y[Row()] = y - yfudgePos
);
);
);
dt << select where(ismissing(:y));
dt << delete rows;
The table it produces looks like
The data table I created has two column. One called X and one called Y The columns can be named whatever one would like to call them. The script just has to be changed to swap out the references to the column names of X and Y to whatever the actual names of the columns are.
Getting back to the actual script that I provided....once the data table is created, I then used Graph Builder to display the data in a graphical form.
Graph Builder( Variables( X( :x ), Y( :y ) ), Elements( Points( X, Y, Legend( 3 ) ) ) );
This JSL statement displayed the sine wave graph.
The next statement simple pauses the execution of the script, to allow one to see the graph for 5 seconds, before moving on to the actual searching for the minimum and maximum values in the data.
Wait( 5 );
Theremainder of the JSL, is the actual working part of the code, that first finds the maximum and minimum point of each sine wave, and then creates a new data table containing just the
Top and Bottom data points for each wave.
// Find the min and max for each phase in the sine waves
dt << New Column("T or B",character);
// determine the starting direction of the wave
if(dt:y[1]<dt:y[2], direction = "up", direction = "down");
For( i = 1, i <= N Rows( dt ) - 1, i++,
If(
direction == "up" & dt:y[i + 1] < dt:y[i],
show(i);
dt:T or B[i] = "Top";
direction = "down";,
direction == "down" & dt:y[i + 1] > dt:y[i],
dt:T or B[i] = "Bottom";
direction = "up";
)
);
dt << select where( :T or B != "" );
dtTB = dt << subset( selected columns(0), selected rows(1));
To apply this analysis to your data, you will first need to input your data into a JMP data table in a structure like the sample data table I generated. Then, assuming your data column were named X and Y, you just need to run the script below, to have it use your new table to analyze the data and find the minimum and maximum values for each wave.
Names Default To Here( 1 );
dt = Current Data Table();
// Find the min and max for each phase in the sine waves
dt << New Column( "T or B", character );
// determine the starting direction of the wave
If( dt:y[1] < dt:y[2],
direction = "up",
direction = "down"
);
For( i = 1, i <= N Rows( dt ) - 1, i++,
If(
direction == "up" & dt:y[i + 1] < dt:y[i],
Show( i );
dt:T or B[i] = "Top";
direction = "down";,
direction == "down" & dt:y[i + 1] > dt:y[i],
dt:T or B[i] = "Bottom";
direction = "up";
)
);
dt << select where( :T or B != "" );
dtTB = dt << subset( selected columns( 0 ), selected rows( 1 ) );
Jim