Optimizing a calculation. Try matrix values to meet a condition.

1 view (last 30 days)
I am learning to write in Matlab, and I wrote a code to calculate this:
  1. I have a column matrix "A" with the posible values to use. To increase the accuracy, I change the step of the increment in the column, for a defined interval.
  2. I use each value of "A" matrix on calculation, this results in a column matrix "B".
  3. I seek for a value in the matrix "B", which meet a condition with "find" command.
  4. I seek the last value for the same position in the "A" matrix. Finally, I found the value to continue my spreadsheet.
Can I optimize this process? Because I'm preparing another code where the value in step 2 is another matrix, and the efficiency of the calculation could increase. Or maybe, only to know the best way to proceed.
Can I use "for", isn't it?
Please, help me.
This is my code:
As1= = 510; fy=420; h = 650; d = 590; Es = 200000;
fc = 21; As2 = 520; b = 350; beta1 = .85;
T = As1*fy/1000;%kN
c = ((0.0001:.000001:1)*h)'; %STEP 1 Interval: 0<c<=h
%STEP 2
eps = (c-d)*.003./c;
fs = Es*eps;
Cs = (fs-.85*fc)*As2/1000;
Cc = beta1*fc*b*.85*c/1000;
C = Cs + Cc;
cond = C - T;
Pc = find(cond>=0); %STEP 3
Pc = min(Pc);
%%%%%%%%%%%%
ccalc = c(Pc,1); %STEP 4

Answers (1)

John D'Errico
John D'Errico on 16 Apr 2018
Edited: John D'Errico on 16 Apr 2018

Why not just use some basic algebra?

I'll do it in MATLAB, as it will be faster that way.

By the way, using eps as a variable is just a bad idea, since eps is far too useful a tool on its own.

As1 = 510; fy=420; h = 650; d = 590; Es = 200000; 
fc = 21; As2 = 520; b = 350; beta1 = .85;
T = As1*fy/1000;%kN
% I'll define c as symbolic here.
syms c
E = (c-d)*.003./c;
fs = Es*E;
Cs = (fs-.85*fc)*As2/1000;
Cc = beta1*fc*b*.85*c/1000;
C = Cs + Cc;
cond = C - T;
cond
cond =
(42483*c)/8000 + (104000*((3*c)/1000 - 177/100))/c - 111741/500
pretty(cond)
          /  3 c   177 \
          | ---- - --- | 104000
42483 c   \ 1000   100 /          111741
------- + --------------------- - ------
  8000              c               500

Perhaps it is easier to just plot cond.

Note the value of h, since you require that c be between 0 and h.

h
h =
   650

So what are you doing with cond?

Pc = find(cond>=0); %STEP 3
Pc = min(Pc);

That is poor MATLAB. READ THE HELP FOR FIND, even though you should not be using use find here anyway.

If you want to find the first instance that makes your condition true, just do this:

Pc = find(cond>=0,1,'first');

Regardless, lets plot cond, as a function of c.

ezplot(cond[0,650])
grid on

The curve is a simple hyperbola. You want to find the smallest value of c that makes cond>=0.

Yes, you say in your question in one place that you want to find the LAST value of c. But that is inconsistent with your code, where you found the FIRST (SMALLEST) value of c.

So here is your function:

condfun = @(c) (42483*c)/8000 + (104000*((3*c)/1000 - 177/100))/c - 111741/500;

Now just use fzero on it. It crosses the axis at the point where cond==0.

[c0,fval] = fzero(condfun,[0.00001,650])
c0 =
       178.04
fval =
  -1.4211e-13

Note that condfun is just slightly less than zero by an amount that is less than the tolerance for convergence. If that bothers you, then you can just bump c0 up by a tiny amount.

condfun(c0 + 1.e-12)
ans =
   1.1227e-11
  1 Comment
Isai Fernandez
Isai Fernandez on 16 Apr 2018
Thanks for your answer. But I don't have the Symbolic Toolbox.
I wrote this:
for c = 0.0001:100:h
es = (d-c)./c*ecu
fs = min( fy, max( -fy, es.*Es) )
F = fs.*As/1000
Cc = beta1*fc*b*.85*c/1000
S = sum(F)-Cc
end
Now, I would like to store all "S" elements from this loop, arranged in a column matrix. Can you help me?
I think that I could identify the "c" value to use.

Sign in to comment.

Tags

Community Treasure Hunt

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

Start Hunting!