Suggestions to improve MATLAB code?

508 views Asked by At

I wonder if anyone has any suggestions to improve the performance, presentation, and/or output of the following MATLAB code?

I have written a program to approximate sin x using a partial sum

((-1)^n)*(x.^((2*n)+1))/(factorial((2*n)+1))

using the methods LS and SL. For LS, I have computed and summed the terms from the largest term first to the smallest term last. For SL, I have done the calulation in the reverse order.

Here is my function:

function ret = taylorsin(x,n)
ret = ((-1)^n)*(x.^((2*n)+1))/(factorial((2*n)+1));
end

and my short code:

function ret = partialsum(x,n,log)
ret = 0;
if log == 1
    for i = 0:1:n
        ret = ret + taylorsin(x,i);
        i=i+1;
    end
elseif log == 0
    for i = n:-1:0
        ret = ret + taylorsin(x,i);
        i = i+1;
    end
end
end

Thanks for any input.

1

There are 1 answers

2
Rody Oldenhuis On BEST ANSWER

On first viewing, a couple of things stand out:

  • you're giving your loop variable the same name as a MATLAB built-in (ii)
  • you're using a variable name that's also the name of a MATLAB built-in (log)
  • you're changing the loop variable inside the loop (ii=ii+1 is not necessary)
  • you're not in-lining the taylorsin function in the loop (function calls to non-built-in functions can be hard to JIT)
  • you're not checking for other values of the variable log (this WILL bite you)

So, a quick improvement would be:

function ret = partialsum(x,n,lg)
ret = 0;
if lg == 1
    for ii = 0:n
        N = cumprod(2 : 2*ii+1);
        ret = ret + (-1)^ii * (x^(2*ii+1))/N(end);
    end
elseif lg == 0
    for ii = n:-1:0
        N = cumprod(2 : 2*ii+1);
        ret = ret + (-1)^ii * (x^(2*ii+1))/N(end);
    end
else
    error('Invalid value for lg');    
end

But given that the outcomes of the computations in the loop are the same (just the summation order is different), you can vectorize the whole thing:

function ret = partialsum(x,n,~)
    ii  = 0:n;  
    k   = 2*ii+1;      
    ret = x.^k ./ factorial(k) * (-1).^ii.';
end