6 views (last 30 days)

Show older comments

Please Help me about a great piecewise fun. by matlab 2013a

for k=1,...,n

This is my code.

function p = my_code(x,h)

for k=2:length(x)

if x >= x(k-1) & x <= x(k-1)+h/3

p(k)=(x(1,:)- x(k-1) ).^3;

elseif x>=x(k-1)+h/3 & x<=(x(k-1)+2*h/3)

p(k) =1/2+(3 *( x(1,:)- x(k-1)-h ));

elseif x >=x(k-1)+2*h/3 & x <= x(k)

p(k)=1+(x(1,:)- x(k) ).^2;

elseif x >=x(k) & x <= x(k)+h/3

p(k)=1-(x(1,:)- x(k)-h ).^2;

elseif x >=x(k)+h/3 & x <= x(k)+2*h/3

p(k) =1/2-(3 *( x(1,:)- x(k)-h ));

elseif x >=(x(k)+2*h/3) & x <=x(k+1)

p(k) =-(x(1,:)- x(k+1) ).^3;

else

p(k) = 0;

end

end

end

when run fun. with

h=0.1;

x=0:h:1;

my_code(x,h)

This is what I'm getting:

ans =

0 0 0 0 0 0 0 0 0 0 0

Also, i have problem about k=1,...,n, because i used form k=2:length(m)

John BG
on 7 Jun 2017

Edited: John BG
on 7 Jun 2017

Hi Work Wolf

this is John BG ( <mailto:jgb2012@sky.com jgb2012@sky.com> ), please comment if the following answers your question, script and support function attached, following my understanding of the question:

% attached files: example_prob_density.m find_nearest_xk.m

1.

Defining a test x:

N=10 % define amount of points in x

x=randi([1 1000],1,10)/100 % generate x points

h=min(abs(diff(x))) % define h, here it's as small as the shortest step among x values

2.

Defining void grid for result, your px(x) I call it pv

dv=.1*h

v=[min(x)-h:dv:max(x)+h]; % this is the grid to be used to calculate pk(x)

pv=zeros(1,numel(v));

3. check

stem(x);hold all;plot(x)

% x=[0 x 0]; not needed

4.

sweep v, not x

for k=1:1:length(v)

[xk xk1 xk2]=find_nearest_xk(v(k),x)

sgna=sign(v(k)-xk)

da=abs(v(k)-xk) % abs(x-x(k)) within [0 h/3]

da1=abs(v(k)-xk1) % abs(x-x(k)) within [h/3 2*h/3]

da2=abs(v(k)-xk2) % abs(x-x(k)) within [2*h/3 h]

if da<=h/3 pv(k)=1-sgna*da;end;

if da1>h/3 && da<2*h/3 pv(k)=.5-3*sgna*(da1-h); end;

if da2>2*h/3 && da<h pv(k)=da2^3*sgna; end;

end

5.

result

figure(2);plot(v,pv)

hold all;stem(x);grid on

.

6.

the support function finds the nearest x(k) to each point of v, which is your input x, not the same as the input sequence of scattered points x [x1 x2 .. xn]

function [y y1 y2]=find_nearest_xk(a,b) % a is a point, b is a a group of points

% calculating length(b) distances to point a

% returning point b(k) closest to a, and adjacent points b(k-1) b(k+1)

% adjacent to b(k), not to a

db=0

for s=1:1:length(b)

db=[db abs(a-b(s))];

end

db(1)=[];

[db n_b]=min(db)

% y=b(n_b)

if n_b==1

y=0;y1=b(1);y2=b(2);

end

if n_b==numel(b)

y=b(numel(b)-1);y1=b(numel(b));y2=0;

end

if n_b>1 && n_b<numel(b)

y=b(n_b-1);y1=b(n_b);y2=b(n_b+1);

end

% m=n_b % not needed, just for debugging

end

7.

comment, please note that in order to keep symmetry and shorten the amount of required Ifs I have used the following expression

8. update

ok, so far pk(x) now does something, not flat anymore, it looks like a noisy sin(v), sort of.

This is because the support function I initially used did not take into account x(k-1) and x(k+1), check 1st email.

I have updated both script and support function to take into account x(k-1) and x(k+1) as requested, check attachments to this answer and 3rd email.

Now, for different random sequences (10 samples only each test) one gets a clear spike, or a couple of them. Sample:

.

Hope it helps.

.

Work Wolf, also to PhD Adel Adel

if you find this answer useful would you please be so kind to consider marking my answer as Accepted Answer?

To any other reader, if you find this answer useful please consider clicking on the thumbs-up vote link

thanks in advance

John BG

Stephen
on 4 Jun 2017

Edited: Stephen
on 4 Jun 2017

In theory your code would work, after a few tweaks. In particular you need to read the if documentation, which states that "An expression is true when its result is nonempty and contains only nonzero elements (logical or real numeric)." Now have a look at the logical comparison that you perform:

if x >= x(k-1) & ...

you compare a scalar x(k-1) with all of x, which if x is non-scalar will give a non-scalar logical output. Following the description in the if documentation the only time the if will execute is when every element of the expression is non-zero (i.e. true), which most likely for your data is never true. Therefore there will always be some false elements, which means that none of those if or elseif statements will execute, which means only the else will execute and the output will be zeros only.

The fix is to compare scalar values, I guess you intended something like this:

if x(k)>= x(k-1) && ...

But personally I would not use if at all, I would use indexing and vectorize the operations. I would show how, but I do not understand the specification shown. In particular the range is specified from [x_k-1 .... x_k+1], for k = 1:n, which in my limited understanding would means that for adjacent k those ranges overlap, which does not make much sense. Maybe I just don't know that notation.

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!