gradient of function from vector to scalar - matlab

I need to write a scalar function that gets a vector with unknown length. I have made an example:
%gets vector and returns x1^1 + x2^2 + ... + xn^n
function [ output ] = func2( x )
u=0;
for j = 1 : length(x)
u = u + x(j)^j;
end
output = u;
end
and
%gets vector and returns sin(x1) + sin(x2) + ... + sin(xn)
function func = func1( x )
func = sum(sin(x));
end
but when I try to calculate gradient of this function I get 0 for example:
func1([1,2,3]) = -0.865837027279448
but
gradient(func1([1,2,3]),[1,2,3]) = 0
I am looking for a way to implement gradient(func1,x) and get cos(x(1)) cos(x(2)) ... (cos(x(n)) so in the example above it suppose to be:
gradient(func1([1,2,3]),[1,2,3]) = [cos(1),cos(2),cos(3)]
Can anyone suggest the best way to approach this problem?

Related

How do I increase stepsize in MATLAB?

For my computing course, I am asked to solve an ODE, using Euler's method.
My code runs, however, I am now asked the following:
"Increase N a number of times, according to N=100,200,400,800.... so you can obtain the answers y100,y200,y400,y800...."
Here's my code:
function [xar,yar] = eulsol(a,b,ybouco,N)
h=(b-a)/N;
T=a:h:b;
y(1)=ybouco;
for i = 100:N
f(i) = -8*y(i) + 0.5*T(i) + (1/16);
y(i+1) = y(i)+h*f(i);
end
xar=T;
yar=y;
end
Can someone help me with obtaining a nice table in MATLAB, which shows me the arrays x and y, according to an increasing N (100,200,400,800....)?
Let's define K as the number of steps. In your example, K=4 (N=100,200,400,800). If N=100,200,400,800,1600,3200 then K = 6
Note that the ith element of N correspond to 100*2^(i-1):
i = 1 => N = 100 * 2^(1-1) = 100
i = 2 => N = 100 * 2^(2-1) = 200
i = 3 => N = 100 * 2^(3-1) = 400
and so on...
So if you want to calculate for N=100,200,400,800, your code should be:
function [xar,yar] = eulsol(a,b,ybouco,K)
N_max = 100 * 2^(K-1)
h=(b-a)/N_max;
T=a:h:b;
y(1)=ybouco;
for i = 1:K
N = 100 * 2^(i-1)
f(N) = -8*y(N) + 0.5*T(N) + (1/16);
y(N+1) = y(N)+h*f(N);
end
xar=T;
yar=y;
end
This answer if for creating the correct N inside the for loop, but you should review your code! As you can see: for i = 1, you have N = 100 and to calculate F(100) you need y(100), but you don't have y(100), just y(1).
Maybe the correct answer is F(i) = -8*y(i) + 0.5*T(N) + (1/16);
But again, want is T(N)?
Please, as noted by #Argyll , explain what you want, you shouldn't expect people to understand your question from a wrong code.

How can I measure length of signal in simulink?

I have model with "matlab function block" in which I have recursive least square method. Recursive algorithm needs to know length of incoming signal in order to work correctly. But when I use command N=length(y) it returns me length N= 1. But I think it should give me higher length.
Simulink model
Matlab function block code "rls_iden6"
function [P,N] = fcn(u,y)
%%
N = length(y);
sigma=1;
C = sigma*eye(2); %p
P = ones(2,1);
z= [y; u];
lamda=1;
for n=1:N
sample_out = y(n);
C = (C - ( (C*z*z'*C)/( lamda+(z'*C*z) ) ))/lamda;
P = P + (C*z* (sample_out - (z'*P)));
end
My final code should look like it's shown below, because it works in matlab workspace. Simulink should give me 5 parameters instead of just 2.
load data_cela.mat
u=U; %input
y=Y; %output
%%
input = 3;
output = 2;
system = input + output;
N = length(y);
%initial conditions
sigma = 1;
C = sigma*eye(system);
P = ones(system,1);
lamda = 1; %forgetting factor
for n=3:N
for i=1:2
W(i) = y(n-i); %output
end
for i=1:3
V(i) = u(n-i+1); %input
end
z = [V';W'];
sample_out = y(n);
pom(n)= z' * P;
error(n) = y(n) - pom(n);
C = (C - ( (C*z*z'*C)/( lamda+(z'*C*z) ) ))/lamda;
P = P + (C*z* (sample_out - (z'*P) ) );
change(1:system,n) = P;
end
f_param = [P(1:3);-P(4:5)];
num = [P(1:3,1)];
den = [1;-P(4:5,1)];
num1 = num(3,1);
trasferfunction = tf(num1,den',1)
Result:
0.002879
----------------------
z^2 - 1.883 z + 0.8873
You will need to add a buffer before signal to convert the scalar to matrix. Then after the buffer has been added set the buffer size to the amount of data you want, i.e. by setting it to 2 will make 2 rows and 1 column. This will help you to get the data however, for setting delay properly you will require to set buffer overlap to 1.
Hope this helps.

Trying to get a MATLAB function to take an array of inputs

I'm trying to call a numerical integration function (namely one that uses the trapazoidal method) to compute a definite integral. However, I want to pass more than one value of 'n' to the following function,
function I = traprule(f, a, b, n)
if ~isa(f, 'function_handle')
error('Your first argument was not a function handle')
end
h = (b-a)./ n;
x = a:h:b;
S = 0;
for j = 2:n
S = S + f(x(j));
end
I = (h/2)*(f(a) + 2*S + f(b)); %computes indefinite integral
end
I'm using; f = #(x) 1/x, a = 1 and b = 2. I'm trying to pass n = 10.^(1:10) too, however, I get the following output for I when I do so,
I =
Columns 1 through 3
0.693771403175428 0.069377140317543 0.006937714031754
Columns 4 through 6
0.000693771403175 0.000069377140318 0.000006937714032
Columns 7 through 9
0.000000693771403 0.000000069377140 0.000000006937714
Column 10
0.000000000693771
Any ideas on how to get the function to take n = 10.^(1:10) so I get an output something like,
I = 0.693771403175428, 0.693153430481824, 0.693147243059937 ... and so on for increasing powers of 10?
In the script where you are calling this from, simply iterate over n
k = 3;
f = #(x)1./x;
a = 1; b = 2;
I = zeros(k,1);
for n = 1:k
I(n) = traprule(f, a, b, 10^n);
end
% output: I = 0.693771403175428
% 0.693153430481824
% 0.693147243059937
Then I will contain all of the outputs. Alternatively you can adapt your function to use the same logic to loop over the elements of n if it is passed
as a vector.
Note, you can improve the efficiency of your traprule code by removing the for loop:
% This loop operates on every element of x individually, and is inefficient
S = 0;
for j = 2:n
S = S + f(x(j));
end
% If you ensure you use element-wise equations like f=#(x)1./x instead of f=#(x)1/x
% Then you can use this alternative:
S = sum(f(x(2:n)));

Summation of function in a for loop (matlab)

Suppose I have a function f(x) = cos(x). I want to evaluate f(x) in a form of g(x) = 1/2*f(0) + sum(1/4*f(a+h*i)) (for i is odd) + sum(3/4*f(a+h*i)) (for i is even except 0 and 10) + 1/2*f(b)
I write the code below, but it did not give the sum of (1/4*f(a+h*i)(for i is odd) and the sum of 3/4*f(a+h*i)(for i is even except 0 and 10).
a=0
h=0.1571
n=10
b=1.5708
for i = 1: n
simp_int2 = 0;
simp_int3 = 0;
simp_int1 = 1/2*f(0)
if i < n
if rem(i,2)~=0
simp_int2 = simp_int2 + 1/4*f(a+h*i)
end
if rem(i,2)==0
simp_int3 = simp_int3 + 3/4*f(a+h*i)
end
end
simp_int4 = 1/2*f(b)
end
simp_int = simp_int1 + simp_int2 + simp_int3 + simp_int4
I also tried cumsum and symsum. Both not working the way I intended. Thanks for any help!
You are resetting the accumulation variables at every iteration. Move the simp_* initializations to outside of the for loop.
Specifically:
a=0
h=0.1571
n=10
b=1.5708
% Change
simp_int1 = 1/2*f(0);
simp_int2 = 0;
simp_int3 = 0;
simp_int4 = 1/2*f(b);
for i = 1: n
if i < n
if rem(i,2)~=0
simp_int2 = simp_int2 + 1/4*f(a+h*i)
end
if rem(i,2)==0
simp_int3 = simp_int3 + 3/4*f(a+h*i)
end
end
end
simp_int = simp_int1 + simp_int2 + simp_int3 + simp_int4;
Since your function will return vector output for vector input you can do this without a for loop:
a=0
h=0.1571
n=10
b=1.5708
simp_int = 1/2*f(0) + sum(1/4*f(a + h*[1:2:n])) + sum(3/4*f(a+h*[2:2:n-1])) + 1/2*f(b)

Matlab remove loop to calculate PT1

I am calculating PT1 behavior in Matlab using the input vector u:
u(20:50,1) = 2;
k = 0.8;
x=zeros(50,1);
for i=2:size(u,1)
x(i) = k*x(i-1) + (1-k)*u(i);
end
How can I remove the for loop to get the same result?
This is actually a first-order IIR filter, so you can use filter for that:
u(20:50, 1) = 2;
k = 0.8;
x = filter(1 - k, [1, -k], u);
If you write x(i) out for a couple of values, you'll see a pattern in it:
x(1) = 0; % since the loop starts at i=2
x(2) = k*x(1) + (1-k)*u(2)
= 0 + (1-k)*u(2)
x(3) = k*x(2) + (1-k)*u(3)
= k*(1-k)*u(2) + (1-k)*u(3)
x(4) = k*x(3) + (1-k)*u(4)
= k^2*(1-k)*u(2) + k*(1-k)*u(3) + (1-k)*u(4)
...
So you'll easily spot the pattern being:
x(i) = (1-k) * sum(k^(i-j)*u(j), j=2..i)
which is now an explicit function.
You could apply this to remove your loop, but in reality this explicit function itself must calculate a large sum. Doing this for every index of x takes probably more time than looping and re-using prior results.