简体   繁体   中英

Matlab piecewise two variables function

I'm trying to plot a piecewise function of two variables, but the code I write doesn't work.

This is my code

c=-0.5;
b=0.5;
L=0:1:100;
K=0:1:100;
[L,K]= meshgrid(L,K);

for i=1:length(L)
    for q=1:length(K)
            if 
            {
            L(i)/K(q)>=-c
            Z=(K(q).^b).*(L(i)+(b.*c).*K(q)).^(1-b);
            else
            Z=((-1/c)^b) .*(1-b).*(1-b);
            }
            end
    end
end
surf(Z)

Can someone help me?

The first problem with your code is the use of the curly braces { ... } . Unlike in many other programming languages (eg C or Java), you do not need any curly braces to group multiple commands together (eg in an if or a for clause). Instead, MATLAB uses the end statement as shown below.

Second, in each iteration you write Z = ... , which Z is overwritten in each iteration. That way, you will get one single number Z at the end of your code. Instead, you should use matrix indexing to write the result of your calculation to the (i,q) -th position in Z . This is as simple as writing Z(i,q) = ...; . While this would already work, you should preallocate your Z matrix, that means you create a matrix of zeros before the for loop. Then MATLAB doesn't have to increase the size of your matrix in each iteration. This is done using the zeros function.

Third, you have to call surf(L,K,Z) instead of surf(Z) to get the axis right: with surf(Z) , they will be from 1 to 101, while they should go from 0 to 100.

As proposed in the previous (now deleted) answer, you do not need to explicitly write .* instead of * , as you are dealing with scalars and not with vectors or matrices. You only need .* if you want to calculate a point-wise multiplication between two vectors/matrices of the same size. With scalars, both works and leads to the same results, but it is not needed at all.

Then, don't use length . length just returns the length of the largest array dimension. If you change K to go from 0 to 1000, or make steps of size 0.1, this will fail. Instead, use size to get the length in a specified dimension. Use the first dimension for i and the second dimension for q .

One more hint: don't use i or j as variables in MATLAB , as they are used to denote the imaginary unit. Just use ii or k or any other name you like. In my opinion, using i and j in for loops is a bad habit - rather use some meaningful names, like rowNumber or imageNumber , or whatever is applicable in your case - so somebody reading the code knows what this really is.

c=-0.5;
b=0.5;
L=0:1:100;
K=0:1:100;
[L,K]= meshgrid(L,K);

% Preallocate Z
Z = zeros(size(L,1), size(K,2));

for ii=1:size(L,1)
    for q=1:size(K,2)
        if L(ii)/K(q)>=-c
            Z(ii,q) = (K(q)^b)*(L(ii)+(b*c)*K(q))^(1-b);
        else
            Z(ii,q) =((-1/c)^b)*(1-b)*(1-b);
        end
    end
end

surf(L,K,Z)

With that, your code runs through without any errors and creates a surface plot as expected.

This is a prime example of where vectorized (all-in-one-operation) matlab coding can bring great benefits in terms of efficiency:

c=-0.5;
b=0.5;
L=0:1:100;
K=0:1:100;

% slow loop-based method - shouldn't use meshgridded L and K here
Z = zeros(length(L), length(K));
for i=1:length(L)
    for q=1:length(K)
        if L(i)/K(q)>=-c
            Z(i,q) = (K(q)^b)*(L(i)+(b*c)*K(q))^(1-b);
        else
            Z(i,q) =((-1/c)^b)*(1-b)*(1-b);
        end
    end
end
figure(1)
surf(L,K,Z)



% much faster vectorized approach
ZZ = zeros(length(L), length(K));
[KK,LL]= meshgrid(K, L);  % corrected order of meshgrid inputs and outputs
                          % ---alternatively you could use [LL,KK]=ndgrid(L,K);
case1 = LL ./ KK >= -c;
case2 = ~case1;
ZZ(case1) = KK(case1).^b .* ( LL(case1) + (b*c) .* KK(case1) ) .^ (1 - b);
ZZ(case2) = ((-1/c)^b)*(1-b)*(1-b);

figure(2)
surf(L,K,ZZ)    

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM