1

I have a problen in scilab How can I plot functions containing if and < like

function y = alpha(t)
   if (t < 227.8) then 
       y = 0.75;
   elseif (t < 300) then
       y = 2.8 - 0.009 .* t;
   else
       y = 0.1;
   end   
endfunction

and

function [r]=minus_alpha(t)
    r = 1 - alpha(t)
endfunction

When I use

x = linspace(0,300)
plot(x, alpha(x))

I got the error message

WARNING: Transposing row vector X to get compatible dimensions
plot2d: falsche Größe für Eingangsargument: inkompatible Größen.
Error 999 : in plot2d called by plot

Sorry for german mix. Thank you.

Stéphane Mottelet
  • 2,853
  • 1
  • 9
  • 26
fravid
  • 11
  • 2

5 Answers5

0

You can avoid explicit loop and be more efficient using the followin code

function y = alpha(t)
   y=0.1*ones(t);
   y(t<227.8)=0.75;
   i=t>=227.8&t<300;
   y(i)=2.8 - 0.009 .* t(i);   
endfunction
user5694329
  • 412
  • 3
  • 3
0

It is really sad to see a great majority of Scilab community is not aware of vectorized operations. You can change your function to:

function y = alpha(t)
   y = 0.1;
   if t < 227.8 then 
       y = 0.75;
   elseif t < 300 then
       y = 2.8 - 0.009 * t;
   end
   y = 1 - y; 
endfunction

and then use feval to broadcast the function over the sequence:

x = linspace(0, 300);
plot2d(x, feval(x, alpha));

which results:

enter image description here

rule of thumb if you are using for loop you need to revise your code and if someone is offering you a code where there is unnecessary for loop you shouldn't probably use it.

Foad S. Farimani
  • 12,396
  • 15
  • 78
  • 193
  • 1
    Using `feval`is not true vectorization because here it does repeated calls to `alpha` although the function itself can be vectorized by using dot operators. – Stéphane Mottelet Apr 02 '19 at 18:24
  • @StéphaneMottelet well, I have explained [here](https://stackoverflow.com/a/55103350/4999991) in details that what I mean by the term vectorzation. This is something I have borrowed from Python lingo used to refer to list comprehension and operations alike to eliminate the need for excessive for loops. It is not parallelism, but just a way to make the code more consise. – Foad S. Farimani Apr 02 '19 at 23:29
0

All the proposed answers are overcomplicated considering that the function alpha in the original demand is piecewise-affine. In Scilab in can be coded that way:

x = linspace(0,400,1000);
plot(x,linear_interpn(x,[227.8 300],[0.75 0.1])) 

i.e. you just have to know the nodes coordinates (here abscissae) and value of the function at nodes. The function linear_interpn does also multilinear interpolation, it is worth knowing it guys...

Stéphane Mottelet
  • 2,853
  • 1
  • 9
  • 26
-1

If you check the output of your alpha(x), you will see that it is just a scalar (not a vector). I guess you wanted something like this, so it's necessary to iterate through t to compute each value of y based on the value of t:

clc;
clear;
function y = alpha(t)
    for i=1:size(t,"*") 
        if t(i) < 227.8 then 
            y(i) = 0.75;
        elseif t(i) < 300 then
            y(i) = 2.8 - 0.009 * t(i);
        else
            y(i) = 0.1;
        end  
    end 
endfunction

x = linspace(0,300);
plot2d(x,alpha(x));

If you find the answer useful, please do not forget to accept it, so others will see that your problem is solved.

Attila
  • 615
  • 4
  • 10
-1

Before your answers (thank you) my workaround was a combination of indicator functions composed with floor and exp( -t^2):

function y = alpha(t)  
    y = floor(exp(-(t .* (t-T1)) / (T1*T1))) * 0.75 
        +  floor(exp(-((t-T2) .* (t- T1) / (2000)))) .* (2.8-0.009 .* t) 
        + floor(exp(-((t-T2) .* (t-1000) / (200000))))*0.1
endfunction
fravid
  • 11
  • 2