GNUPLOT : Plotting a user defined equations which operates indifferent intervals - function

Hi there I need some help!
I am new to Gnuplot and have difficulties with the scripts.
Actually my equation is a lot more complicated. It is a parametric equation consisting of 7 parts each defined into a specific interval, with a bunch of parameters.
I just need a lead. So let me simplify the problem.
Suppose I have a function defined as follows f(x)= a*x+cos(x) : for 0 <= x <= 3;
and f(x)= b*1/cos(x) : for 3 < x <=10
my question is how do I instruct GNUPLOT:
1-) to consider "a" and "b" as parameters
2-) to plot "my user-defined" equation into the intervals of definition of f(x)
So far I have used the "set parametric" command but the problem is always at the end at the "PLOT f(x)" command for which I really don't know how to deal with the intervals.
I am using Windows 7 with the latest gnuplot.
Please help

You can define your f(x) as a (conditional) piece-wise function:
f(x) = 0 <= x && x <= 3 ? a*x+cos(x) : 3 < x && x <= 10 ? b/cos(x) : 1/0
The 1/0 above makes sure the function is not defined outside of the given intervals. The parameters a and b are already implicitly treated as parameters by gnuplot. When you change their values, f(x) is updated automatically. Example:
set xrange [-2:12]
a = 1.; b = 1.
plot f(x)
If you want more flexibility, you can take a and b as variables and do the following:
f(x,a,b) = 0 <= x && x <= 3 ? a*x+cos(x) : 3 < x && x <= 10 ? b/cos(x) : 1/0
set xrange [-2:12]
plot f(x,1,1), f(x,2,3)

Related

Removing DC component for matrix in chuncks in octave

I'm new to octave and if this as been asked and answered then I'm sorry but I have no idea what the phrase is for what I'm looking for.
I trying to remove the DC component from a large matrix, but in chunks as I need to do calculations on each chuck.
What I got so far
r = dlmread('test.csv',';',0,0);
x = r(:,2);
y = r(:,3); % we work on the 3rd column
d = 1
while d <= (length(y) - 256)
e = y(d:d+256);
avg = sum(e) / length(e);
k(d:d+256) = e - avg; % this is the part I need help with, how to get the chunk with the right value into the matrix
d += 256;
endwhile
% to check the result I like to see it
plot(x, k, '.');
if I change the line into:
k(d:d+256) = e - 1024;
it works perfectly.
I know there is something like an element-wise operation, but if I use e .- avg I get this:
warning: the '.-' operator was deprecated in version 7
and it still doesn't do what I expect.
I must be missing something, any suggestions?
GNU Octave, version 7.2.0 on Linux(Manjaro).
Never mind the code works as expected.
The result (K) got corrupted because the chosen chunk size was too small for my signal. Changing 256 to 4096 got me a better result.
+ and - are always element-wise. Beware that d:d+256 are 257 elements, not 256. So if then you increment d by 256, you have one overlaying point.

A simple math in Python that's hard for me

Please help me. I'm trying to learn Python and I'm very beginner. I tried reading and watching videos but I don't understand this logic:
def myFunction(y):
x = y + y #Local
print(x)
return x
x = 5 #Global
myFunction(x)
print(x)
I get the values 10 and 5.
Really, I can't understand why 10. This is breaking my mind. If x equals 5, than the result of the line 2 shouldn't be 2.5? I have 5 = y + y.
My mind is on a loop. Please help, you're my only hope.
You are passing x as the argument of your function myFunction().
Thus if x=5 you get:
myFunction(5):
x = 5 + 5
return(x) #10
this is why you are getting 10. If you change x=5 to x=10 you will see that the result of the function will be 20 and so on...
You are not replacing the x in the function itself. However, the x you stated will indeed remain a global variable and thus will be printed on the second line.

Matlab function in fmincon with fixed value

I have a simple model where I want to minimize the RMSE between my dependent variable y and my model values. The model is: y = alpha + beta'*x.
For minimization, I am using Matlab's fmincon function and am struggling with multiplying my parameter p(2) by x.
MWE:
% data
y = [5.072, 7.1588, 7.263, 4.255, 6.282, 6.9118, 4.044, 7.2595, 6.898, 4.8744, 6.5179, 7.3434, 5.4316, 3.38, 5.464, 5.90, 6.80, 6.193, 6.070, 5.737]
x = [18.3447, 79.86538, 85.09788, 10.5211, 44.4556, 69.567, 8.960, 86.197, 66.857, 16.875, 52.2697, 93.971, 24.35, 5.118, 25.126, 34.037, 61.4445, 42.704, 39.531, 29.988]
% initial values
p_initial = [0, 0];
% function: SEE BELOW
objective = #(p) sqrt(mean((y - y_mod(p)).^2));
% optimization
[param_opt, fval] = fmincon(objective, p_initial)
If I specify my function as follows then it works.
y_mod = #(p) p(1) + p(2).*x
However, it does not work if I use the following code. How can I multiply p(2) with x? Where x is not optimized, because the values are given.
function f = y_mod(p)
f = p(1) + p(2).*x
end
Here is the output from a script that has the function declaration:
>> modelFitExample2a
RMS Error=0.374, intercept=4.208, slope=0.0388
And here is code for the above. It has many commented lines because it includes alternate ways to fit the data: an inline declaration of y_mod(), or a multi-line declaration of y_mod(), or no y_mod() at all. This version uses the multi-line declaration of y_mod().
%modelFitExample2a.m WCR 2021-01-19
%Reply to stack exchange question on parameter fitting
clear;
global x %need this if define y_mod() separately, and in that case y_mod() must declare x global
% data
y = [5.0720, 7.1588, 7.2630, 4.2550, 6.2820, 6.9118, 4.0440, 7.2595, 6.8980, 4.8744...
6.5179, 7.3434, 5.4316, 3.3800, 5.4640, 5.9000, 6.8000, 6.1930, 6.0700, 5.7370];
x = [18.3447,79.8654,85.0979,10.5211,44.4556,69.5670, 8.9600,86.1970,66.8570,16.8750,...
52.2697,93.9710,24.3500, 5.1180,25.1260,34.0370,61.4445,42.7040,39.5310,29.9880];
% initial values
p_initial = [0, 0];
%predictive model with parameter p
%y_mod = #(p) p(1) + p(2)*x;
% objective function
%If you use y_mod(), then you must define it somewhere
objective = #(p) sqrt(mean((y - y_mod(p)).^2));
%objective = #(p) sqrt(mean((y-p(1)-p(2)*x).^2));
% optimization
options = optimset('Display','Notify');
[param_opt, fval] = fmincon(objective,p_initial,[],[],[],[],[],[],[],options);
% display results
fprintf('RMS Error=%.3f, intercept=%.3f, slope=%.4f\n',...
fval,param_opt(1),param_opt(2));
%function declaration: predictive model
%This is an alternative to the inline definition of y_mod() above.
function f = y_mod(p)
global x
f = p(1) + p(2)*x;
end
carl,
The second method, in which you declare y_mod() explicitly (at the end of your script, or in a separate file y_mod.m), does not work because y_mod() does not know what x is. Fix it by declaring x global in the main program at the top, and declare x global in y_mod().
%function declaration
function f = y_mod(p)
global x
f = p(1) + p(2)*x;
end
Of course you don't need y_mod() at all. The code also works if you use the following, and in this case, no global x is needed:
% objective function
objective = #(p) sqrt(mean((y-p(1)-p(2)*x).^2));
By the way, you don't need to multiply with .* in y_mod. You may use *, because you are multiplying a scalar by a vector.

Perform a vectorized exponential moving average in octave

In GNU Octave, would like to calculate an n-day exponential moving average of a vector without using a for-loop.
I am able to do this with a for loop but it is inefficient. I would like to use the filter function, however I am unsure how to get this to work correctly.
After piecing together the bits from this thread
http://octave.1599824.n4.nabble.com/vectorized-moving-average-td2132090.html
I built this function using Octave's filter function.
function meanV = movingEMean(V, window)
simpleAvg = mean(V(1:window));
alpha = 1/window;
X = V(window:end);
X(1) = simpleAvg;
meanV = filter(alpha, [1 alpha-1], X, simpleAvg*(1-alpha));
end
It starts with the simple moving average as the basis. V is the column vector of numbers to calculate the exponential moving average. window is an integer as a number of days. I used 12.
Here is a mathematical explanation of this function.
http://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average
Note that the page uses 2/(n+1) (where n is window or the number of days) as alpha, but I use 1/n because that value of alpha fits my needs. Adjust alpha as needed.
Alternatively, I sometimes need my input and output vector's dimensions to match. I fill invalid values with NaN by adding meanV = [NaN(window-1,1); meanV]; as the last line in the movingEMean function. You could also fill it with simpleAvg if you want a rough estimate.
Reinventing the wheel on octave exponential moving average for a vector is silly. Just copy and paste movavg.m function defined in the octave financial package here: https://octave.sourceforge.io/financial:
function [varargout] = movavg(asset, lead, lag, alpha = 0)
if nargin < 3 || nargin > 4
print_usage ();
endif
if lead > lag
error ("lead must be <= lag")
elseif ischar (alpha)
if ! strcmpi (alpha, "e")
error ("alpha must be 'e' if it is a char");
endif
elseif ! isnumeric (alpha)
error ("alpha must be numeric or 'e'")
endif
## Compute the weights
if ischar (alpha)
lead = exp(1:lead);
lag = exp(1:lag);
else
lead = (1:lead).^alpha;
lag = (1:lag).^alpha;
endif
## Adjust the weights to equal 1
lead = lead / sum (lead);
lag = lag / sum (lag);
short = asset;
long = asset;
for i = 1:length (asset)
if i < length (lead)
## Compute the run-in period
r = length (lead) - i + 1:length(lead);
short(i) = dot (asset(1:i), lead(r))./sum (lead(r));
else
short(i) = dot (asset(i - length(lead) + 1:i), lead);
endif
if i < length (lag)
r = length (lag) - i + 1:length(lag);
long(i) = dot (asset(1:i), lag(r))./sum (lag(r));
else
long(i) = dot (asset(i - length(lag) + 1:i), lag);
endif
endfor
if nargout > 0
varargout{1} = short;
else
plot((1:length(asset))', [asset(:), long(:), short(:)]);
endif
if nargout > 1
varargout{2} = long;
endif
endfunction
And invoke thustly:
foo = [NaN; 1;4;8;10;-3;3;4;0;0;3;4;5;6;7;8;9];
lead = 7
lag = 7
alpha = 'e'
movavg(foo, lead, lag, 'e')
Which prints:
NaN
NaN
NaN
NaN
NaN
NaN
NaN
3.39851
1.24966
0.45742
2.06175
3.28350
4.37315
5.40325
6.41432
7.42128
8.42441

Passing a function as a parameter in a MATLAB function [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Passing a function as argument to another function
Below is a simple code for the bisection method. I would like to know how to be able to pass in any function I choose as a parameter instead of hard coding functions.
% This is an implementation of the bisection method
% for a solution to f(x) = 0 over an interval [a,b] where f(a) and f(b)
% Input: endpoints (a,b),Tolerance(TOL), Max # of iterations (No).
% Output: Value p or error message.
function bjsect(a,b,TOL,No)
% Step 0
if f(a)*f(b)>0
disp('Function fails condition of f(a),f(b) w/opposite sign'\n);
return
end
% Step 1
i = 1;
FA = f(a);
% Step 2
while i <= No
% Step 3
p = a +(b - a)/2;
FP = f(p);
% Step 4
if FP == 0 || (b - a)/2 < TOL
disp(p);
return
end
% Step 5
i = i + 1;
% Step 6
if FA*FP > 0
a = p;
else
b = p;
end
% Step 7
if i > No
disp('Method failed after No iterations\n');
return
end
end
end
% Hard coded test function
function y = f(x)
y = x - 2*sin(x);
end
I know this is an important concept so any help is greatly appreciated.
The simplest method is using anonymous functions. In your example, you would define your anonymous function outside bjsect using:
MyAnonFunc = #(x) (x - 2 * sin(x));
You can now pass MyAnonFunc into bjsect as an argument. It has the object type of function handle, which can be validated using isa. Inside bjsect simply use MyAnonFunc as if it is a function, ie: MyAnonFunc(SomeInputValue).
Note, you can of course wrap any function you've written in an anonymous function, ie:
MyAnonFunc2 = #(x) (SomeOtherCustomFunction(x, OtherInputArgs));
is perfectly valid.
EDIT: Oops, just realized this is almost certainly a duplicate of another question - thanks H. Muster, I'll flag it.