Can someone kindly answer me or give me a hint as soon as possible ?

**You are now following this question**

- You will see updates in your activity feed.
- You may receive emails, depending on your notification preferences.

7 views (last 30 days)

Show older comments

Good day everyone,

Please, I wish if someone can kindly help me to solve the following problem. I wrote the code in the attached file on Matlab R2020a to generate a trapezoidal wave, then analyze it , it was running perfectly, then suddenly when I started to run the code, it sarted to take an extemely long time to finsh the running process. I tried to check if the problem is from my lap top, that's why, I ran the same code on another lap top with a different matlab version R2017b , however the result was the same and the running time can be up to two or three hours. I wish if someone can kindly offer some help as soon as possible .

Thank you so much .

Mostafa Abotaleb
on 23 Jul 2021

Can someone kindly answer me or give me a hint as soon as possible ?

dpb
on 23 Jul 2021

Hint: Attach the m-file as code text -- use the CODE buttons to format it to be legible.

Guess: You didn't preallocate an output vector/array and are building it by dynamic addressing. If the problem size is large, this can be the cause of such a symptom.

Mostafa Abotaleb
on 24 Jul 2021

clc;

f=input('enter the frequency ...');

x = 0:0.000001:10;

y1 = 1*(asind(sin((2*pi*f)*x+1)))-0.5;

y2 = 1*(asind(sin((2*pi*f)*x+1))+acosd(cos((2*pi*f)*x+1)))-1/2;

y3 = 1*(acosd(cos((2*pi*f)*x+1)))-1/2;

massimo = max(y2);

minimo = min(y2);

y4 = y2/massimo;

subplot(4,1,1);

plot(x,y1);

subplot(4,1,2);

plot(x,y2);

subplot(4,1,3);

plot(x,y3);

y7 = y4;

for dd=1:length(y4)

if y4(dd)<0

y4(dd)= 0;

end

end

subplot(4,1,4);

plot(x,y4);

figure;

plot(x,y4);

y5 = y4;

y6 = y4;

for uu = 1:length(y4)

tt = uu + 1

if tt < length(y4)

subtra = y4(uu) + y4(tt);

if subtra >= 1 && subtra < 2;

y4(uu) = sym(y4(uu));

end

end

end

counterones = 0;

counterzeros = 0;

fc1 = [];

fc0 = [];

insert1 = 0;

insert0 = 0;

for ww = 1:length(y4)

qq = ww + 1;

if qq < length(y4)

if y4(ww)==1 && y4(qq) == 1

counterones = counterones + 1

end

if y4(ww)==0 && y4(qq)==0

counterzeros = counterzeros + 1

end

if y4(ww)==1 && y4(qq)<1

insert1 = counterones + 1;

counterones =0;

fc1 = [fc1 insert1];

end

if y4(ww)==0 && y4(qq)>0

insert0 = counterzeros + 1;

counterzeros =0;

fc0 = [fc0 insert0];

end

end

insert0 = 0;

insert1 = 0;

end

Mostafa Abotaleb
on 24 Jul 2021

Mostafa Abotaleb
on 24 Jul 2021

dpb
on 24 Jul 2021

for dd=1:length(y4)

if y4(dd)<0

y4(dd)= 0;

end

end

is just

y4=max(y4,0);

instead of the loop...will save a little.

But, the real problem is precisely what I guessed -- you're building a new array dynamically by concatnenation in the following code segment. This causes a reallocation and recopy of the data every time that is terribly time consuming.

if y4(ww)==1 && y4(qq)<1

insert1 = counterones + 1;

counterones =0;

fc1 = [fc1 insert1];

end

if y4(ww)==0 && y4(qq)>0

insert0 = counterzeros + 1;

counterzeros =0;

fc0 = [fc0 insert0];

end

I didn't try to read the code to decipher precisely what you're wanted result is, but your problem is in the above that doesn't preallocate the two new vectors and copy into them the data wanted at the locations instead appending a new value onto the end.

Describe the output in words that is wanted here...

Mostafa Abotaleb
on 24 Jul 2021

Thank you so much for your reply another time , regarding the purpose of this part of the code that you mentioned in your answer, its purpose is to count the number of ones and zeros in each single trapezoidal wave form and accumulate each of them in two arrays fc1 and fc0, however I noticed that the code takes longer time in this attached part of the code, the purpose of this part is to convert all the values of 1.0000 into only '1' . I tried many functions like 'round' , 'fix' and others , but unfortunately , it didn't workout . it worked out only with the function 'sym', in the line

' y4(uu) = sym(y4(uu));'

for uu = 1:length(y4)

tt = uu + 1

if tt < length(y4)

subtra = y4(uu) + y4(tt);

if subtra >= 1 && subtra < 2;

y4(uu) = sym(y4(uu));

end

end

end

dpb
on 24 Jul 2021

if y4(ww)==1 && y4(qq)<1

You just above turned all y4<1 to 0 so the above can never be true

for uu = 1:length(y4)

tt = uu + 1

if tt < length(y4)

...

Don't use the inner if, just use

for uu = 1:numel(y4)-1

tt = uu + 1

...

Also, what's the point of using sym in sym(y4(uu))? It serves no purpose but will definitely add a lot of overhead as symbolic. What is the point of this in the end?

Mostafa Abotaleb
on 24 Jul 2021

regarding this part :

if y4(ww)==1 && y4(qq)<1

qq = ww+1, so iam checking the condition when the falling edge of the signal will start , detecting the last element of 1

Regarding the second part :

for uu = 1:numel(y4)-1

tt = uu + 1

Thank you so much , I will modify it.

regarding the use of sym(y4(uu) , I mentionede in mylast answer that I would like to convert all the values of 1.0000 into only '1' , because otherwise I am not able to make any comparison operation on them , I tried to use 'round' and 'fix' , but it didn't work out

dpb
on 24 Jul 2021

No. You're confusing the display format of the value with the value. And, if y4(uu) isn't identically the integer 1, then sym(y4(uu)) won't be, either.

If there is some rounding in the initial values that you want defuzzified, then round or fix is definitely the operation you're looking for.

None of this, however, fixes the big problem of building the arrays fc0 and fc1 dynamically which is where the time bottleneck of the first order is.

If you're simply looking for (+/-) crossings, then start with

y=sign(y); y(y==0)=1; % convert to +/- inidicators, count 0 as +ive

dy=diff(y); % gives sign change [0, +/-2]

which gives you a vector first of [-1,1] and then the sign changes of dy==2 or -2 for +ive, -ive crossing locations. Remember to use an offset of 1 because numel(dy) is one less than numel(y) after take difference.

No loops are needed at all...

Mostafa Abotaleb
on 24 Jul 2021

dpb
on 24 Jul 2021

SHOW US!!! DON'T JUST TELL US!!!

I don't believe you understand and that there's really a difference other than the formatting of the display at the command window of the value. If, indeed sym() turned it into a visible "1" then that proves that the value itself internally is, indeed, identically the integer 1.

And, again, you've not solved the problem that is the time crunch; the code I showed above will run in milliseconds over the whole vector.

dpb
on 24 Jul 2021

>> x = 0:0.000001:10; y=rand(size(x))-0.5;

>> tic,y=sign(y);y(y==0)=1;dy=diff(y);fp=find(dy==2);fn=find(dy==-2);toc

Elapsed time is 0.230929 seconds.

>>

fn, fp above are the +/-xings for the given y that is the size of your original vector. This is a 15-yr old lower-middle-class machine that wasn't at all fast for its time, what more now and it took only 1/4-sec.

Mostafa Abotaleb
on 24 Jul 2021

dpb
on 24 Jul 2021

No disrespect intended -- just to emphasize it helps to show us the data itself, not to just describe a symptom. "Help us help you!"

There's no rounding code anywhere in what you have posted so we can't see what you tried, specifically that you thought didn't work, and I don't have the symbolic TB so can't run your code as is, even if I were to download it.

Just attach a section of the y4() array that has an element that is one that you think you need sym() for as a .mat file so can see just what it is that you're geting...

As for the code running, sure it'll run -- but you already pointed out in the beginning you needed the resolution to model a very high sampling rate accurately -- so running it at a much reduced rate doesn't solve the real problem while the solution I showed works for the sizes of vectors you really have an eliminates the rounding issues entirely, whatever they might be.

dpb
on 24 Jul 2021

for uu = 1:length(y4)

tt = uu + 1

if tt < length(y4)

subtra = y4(uu) + y4(tt);

if subtra >= 1 && subtra < 2;

y4(uu) = sym(y4(uu));

end

end

end

is

subtra=sum([y4(1:end-1);y4(2:end)]);

ix=(subtra>=1) && (subtra<2);

y4(uu) = sym(y4(uu));

but I still don't see the point/purpose of any of it.

It just looks like an effort to code sign in a round about way to me. What's the point of the addition of the two adjacent elements instead of just using the signal itself?

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

Start Hunting!**An Error Occurred**

Unable to complete the action because of changes made to the page. Reload the page to see its updated state.

Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .

Select web siteYou can also select a web site from the following list:

Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.

- América Latina (Español)
- Canada (English)
- United States (English)

- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)

- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)