gnuplot--iteration to obtain variables in datafile - loops

Let's say that I've got data called 'myData.dat' in the form
x y
0 0
1 1
2 2
4 3
8 4
16 5
I need to find the following things from this data:
slope for points
0 to 5
1 to 5
2 to 5
3 to 5
4 to 5
y-intercept for the same pairs
equation for the line connecting the same pairs
Then I need to plot the the data and overlay the lines; below is a picture of what I'm asking for.
I know how to obtain the the slope and y-intercept for a single pair of points, and plot the data and the equation of the line. For example for points 1 and 5:
set table
plot "myData.dat" using 0:($0==0 ? y1=$2 : $2)
plot "myData.dat" using 0:($0==4 ? y5=$2 : $2)
unset table
m1 = (y5 - y1)/(5-1)
b1 = y1 - m1*1
y1(x) = m1*x + b1
I'm new to iteration (and gnuplot) and I think there's something wrong with my syntax. I've tried a number of things and they haven't worked. My best guess is that it would be in the form
plot for [i=1:4] using 0:($0==1 ? y.i=$1 : $1)
do for [i=1:5]{
m.i = (y5 - y.i)/(5-i)
b.i = y.i - m.i*1
y.i(x) = m.i*x + b.i
}
set multiplot
plot "myData.dat" w lp
plot for [i=1:4] y.1(x)
unset multiplot
So what is going wrong? Is gnuplot able to concatencate the loop counter to variables?

Your syntax is incorrect. Although there are other ways to do what you want, for instace using word(var,i), the most straightforward fix to what you already have would be to use eval to evaluate a string to which you can concatenate variables:
do for [i=1:5]{
eval "m".i." = (y5 - y".i.")/(5-".i.")"
eval "b".i." = y".i." - m".i."*1"
eval "y".i."(x) = m".i."*x + b".i
}

Related

Creating mesh from 3-column table in matlab

I have a table with values extracted from a csv I want to make a contour plot from.
Let's use this table as an example
tdata.x = [1;2;1;2];
tdata.y = [3;3;4;4];
tdata.z = randn(4,1);
tdata=struct2table(tdata);
>> tdata
tdata =
4×3 table
x y z
_ _ _______
1 3 0.53767
2 3 1.8339
1 4 -2.2588
2 4 0.86217
I would like to pivot this such that I can use it for plotting a contour, so in principle I want a 2x2 z matrix where rows/columns are given by y and x respectively, something in this direction:
x 1 2
y
3 0.53767 1.8339
4 -2.2588 0.86217
where the first row are the x coordinates, the first columns is the y coordinates and in-between are the corresponding z-values. So that is to say the z-value corresponding to (x,y)=(1,4) is -2.2588.
Note, I am going to use this grid for other things down the road so solutions involving interpolation are not valid, as well the data is guaranteed to be given on a grid.
You can use unstack, i.e.
t = unstack( tdata, {'z'}, {'x'} );
Which will give you this:
Note that the column names are all prefixed with x because you can't have a column name beginning with a number. You should be able to extract the x values back again, especially if they're always integers it won't be too hard, for whatever operations you want from here...
Here's the approach I would use:
result = full(sparse(findgroups(tdata.y), findgroups(tdata.x), tdata.z));
Equivalently, you could use the third output of unique instead of findgroups, or accumarray instead of sparse:
[~, ~, ux] = unique(tdata.x);
[~, ~, uy] = unique(tdata.y);
result = accumarray([uy ux], tdata.z);

How to read specific column with specific row in x_test using python

I have a dataset with four input. here I am trying to predict X1 input in next time period using lstm model.
Here I put x_train 80% and x_test 20% .
In x_test first input some of rows are with 0 values.
What I want is I want to read that 0 value separately. I tried and it didn't work for me. Can anyone help me to solve this problem.
Here my code:
data=data.values
scaler_x = preprocessing.MinMaxScaler(feature_range =(0, 1))
x = np.array(x).reshape ((len(x),4 ))
x = scaler_x.fit_transform(x)
scaler_y = preprocessing.MinMaxScaler(feature_range =(0, 1))
y = np.array(y).reshape ((len(y), 1))
y = scaler_y.fit_transform(y)
train_end = 80
x_train=x[0: train_end ,]
x_test=x[train_end : ,]
y_train=y[0: train_end]
y_test=y[train_end :]
x_train=x_train.reshape(x_train.shape +(1,))
x_test=x_test.reshape(x_test.shape + (1,))
After writing code for lstm I tried to predict value for x_test. Before that I want to specify that rows with 0 values.
x_test_n = np.flip(x_test_n, axis=0)
curr_frame = x_test_n[0]
Then it just read first row with four input together.
What I want is to read first input with 0 values.
Image for what I got:
What I want to read

Store formulas as an element of an array in Matlab

(* I don't know programming in Matlab. It is just a general question about Matlab language. *)
In Excel, we can store a formula in a cell. For instance, if A2 contains a formula = A1+10, the re-evaluation of A2 returns 30 when the value of A1 is 20.
My question is, is there a similar mechanism in matlab? That said, can we specify a formula in a element of an array in Matlab, so that we can re-evaluate the array later?
Edit 1:
Following the comment of #rayryeng I try to make an example to illustrate the concept... Actually, this is exactly what spreadsheet languages such as Excel can do.
So my question is, is there a mechanism that permits the following in Matlab? (Note that the following syntax is just symbolic)
>> B = [1 2; B{1,1}+2 4] // store some values and a formula in the array
B =
1 2
3 4
>> B{1,1} = 10 // change the value of one cell
B =
10 2
3 4
>> EVAL(B) // there is a re-evaluation command to re-calculate all the cells
ans =
10 2
13 4
Hopefully I'm understanding what you want correctly, but the answer is indeed yes. You can store "formulas" in a cell array where each element is a handle or an anonymous function.
Perhaps you mean something like this:
formulae = {#(x) x+10, #sin, #cos, #(x) x / 3};
The syntax # denotes a function handle and the (x) denote that this is an anonymous function with the input variable x. The first cell element provides a function that adds 10 to every value that goes into it, the second and third parameters are handles to sin and cos, so these act like those trigonometric functions. The last handle divides every value that goes into it by 3.
To demonstrate, let's create a small array, then go through each formula and apply each of them to the small array:
>> formulae = {#(x) x+10, #sin, #cos, #(x) x / 3};
>> A = [1 2; 3 4]
A =
1 2
3 4
>> formulae{1}(A)
ans =
11 12
13 14
>> formulae{2}(A)
ans =
0.8415 0.9093
0.1411 -0.7568
>> formulae{3}(A)
ans =
0.5403 -0.4161
-0.9900 -0.6536
>> formulae{4}(A)
ans =
0.3333 0.6667
1.0000 1.3333
We first create the formulae, then create a small 2 x 2 matrix of [1 2; 3 4]. After, we access each formula's cell, then put in the input A into the function and we get what you see.
However, when you're starting out, start with actually declaring functions in function scripts.... don't use this kind of style of programming for practical applications. It makes your code less readable. For example, doing sin(A) is much more readable than formula{2}(A). People reading your code have to remember what position in the array corresponds to what formula you are applying to each element in the input.

How to compare each matrix to mean and return value in Matlab

for example lets consider
a = fix(8 * randn(10,5));
and mean(a) would give me mean of each column.
So, what I was planning to do was comparing the mean of first column to each of its content till the column and and proceed to the next column with its mean and comparing with each of its content.
I was able to get this code here (I know there are multiple for loops but thats the best I could come up with, any alternate answer would be greatly accepted)
if(ndims(a)==2)
b = mean(a);
for c = 1:size(a,2)
for d = 1:size(a)
for e = 1:size(b,2)
if(a(d,c)>b(1,c))
disp(1);
else
disp(false);
end
end
end
end
else
disp('Input should be a 2D matrix');
end
I don't know if this is the right answer? Could any one tell me?
Thanks in advance.
It seems you want to know whether each entry is greater than its column-mean.
This is done efficiently with bsxfun:
result = bsxfun(#gt, a, mean(a,1));
Example:
a =
3 1 3 2
5 2 3 1
1 3 5 2
The column-means, given by mean(a,1), are
ans =
3.000000000000000 2.000000000000000 3.666666666666667 1.666666666666667
Then
>> result = bsxfun(#gt, a, mean(a,1))
result =
0 0 0 1
1 0 0 0
0 1 1 1
If you are trying to do what I think you are (print one if the average value of a column is greater than the value in that column, zero otherwise) you can eliminate a lot of loops doing the following (using your same a and b):
for ii=1:length(b)
c(:,ii) = b(ii) > a(:,ii);
end
c will be your array of ones and zeros.

Calculate the center of adjacent values in an array

I created an array of values:
binBorder=exp(0:5)
# 1.000000 2.718282 7.389056 20.085537 54.598150 148.413159
which gives me an array with the length 6 in this case. Now I want to create a second array, which contains the the number which is exactly between thos two numbers. This should give an array of the size of five in this case and contain the values:
1.000000 - ( 1.000000 - 2.718282) / 2
2.718282 - ( 2.718282 - 7.389056) / 2
7.389056 - ( 7.389056 - 20.085537) / 2
20.085537 - (20.085537 - 54.598150) / 2
54.598150 - (54.598150 - 148.413159) / 2
Is there a built-in function for such things? I need it for the calculation of the bin center (that should be a common problem). Or is the following code the "easiest solution"?
> bb1 = exp(0:4)
> bb2 = exp(1:5)
> bb = bb1 + ((bb2 - bb1) / 2)
> bb
I'm a newcomer to R so I'm not sure how problems are generally solved. Is it more built-in functions or constructing things like the solution that I made up?
Thanks for your help,
Sven
Your solution can be rewritten using subsetting to avoid the intermediate variables:
(binBorder[1:5]+binBorder[-1])/2
[1] 1.859141 5.053669 13.737297 37.341843 101.505655
In fact, more generally you could write the following function:
midPoints <- function(x){
(x[-length(x)]+x[-1])/2
}
The function filter does what you are asking for. When used in the following way, it calculates the 2-period moving average:
filter(binBorder, c(0.5, 0.5), sides=1)
Time Series:
Start = 1
End = 6
Frequency = 1
[1] NA 1.859141 5.053669 13.737297 37.341843 101.505655
The only (slight) downside of filter is that it returns a value of class ts (for time series).
You can avoid that by calling convolve:
convolve(binBorder, c(0.5, 0.5), type="filter")
[1] 1.859141 5.053669 13.737297 37.341843 101.505655
Isn't this easily handled by diff()?
binBorder <- exp(0:5)
binBorder[1:5] + diff(binBorder)/2

Resources