Turn on suggestions

Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

Showing results for

Options

- RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Mute
- Printer Friendly Page

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

Posted 11-12-2014 05:00 AM
(1896 views)

Just for fun I wrote the IML module below to return an n x n Pascal matrix. The lower triangular part of the matrix contains Pascal's triangle, and it is zero above the main diagonal.

start Pascal( n );

a = row( j(n, n) ) >= col( j(n, n) );

return( a # comb( (row(a) - 1) # a, (col(a) - 1) # a ) );

finish;

It occurred to me that the COMB function makes this much harder than it should be, as ideally I would like COMB(n,r) to return zero when r>n, rather than returning a missing value. Compare this to Wolfram Alpha which does return zero, as it evaluates factorials of negative integers to be infinite (Google does the same when you enter something like '1 choose 2').

If you would like to try the module, the Pascal matrix certainly has an interesting inverse and its back-diagnonals sum to the Fibonacci numbers.

4 REPLIES 4

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

An interesting question. Thanks for asking. I will let others weigh in before I post my opinions.

Although you do not have a programming question, I also think that your function is very interesting. You have created a single elegant matrix expression that evaluates n##2 quantities. However, in this case the elegance is also causing a problem, since you have to use extra care to avoid invalid arguments.

Although I like your concise formulation, an alternative programming solution is to use a simple loop, which avoids the situation that you have broached:

start PascalTriangle(n);

m = j(n,n,0); /* pad with zeros */

do k = 1 to n;

m[k,1:k] = comb(k-1, 0:k-1); /* fill nonzero elements */

end;

return(m);

finish;

There is also a way to form the triangle by using a single vector computation without a loop:

start BinomCoef(n);

m = shape(1:n##2, n, n);

idx = vech(m);

row = row(m)-1;

col = col(m)-1;

P = j(n,n,0);

P[idx] = comb( row[idx], col[idx] );

return(P);

finish;

Both algorithms are very fast. Notice that you can't compute a Pascall triangle with more than 1029 rows because the binomial coefficients overflow.

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

I would say NO to the question. The COMB function is basically the N choose R. This would be a different function entirely as I'm not sure how a negative factorial should be calculated (in the classic N choose R definition).

And what is the interpretation of the function when R>N? Possibly a new function but the utility in general is ??

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

Yes, I do like Rick's suggestion of the zero coefficients for the higher powers, plus there is a completely natural way of getting there using the gamma function. This, I imagine, is the mechanism behind the Wolfram Alpha and Google implementations of the n choose r function. If I write my own version of the COMB function:

start icomb(n, r);

return( round( gamma(n + 1) / (gamma(r + 1) # gamma(n - r + 1 + 1E-12))));

finish;

all I need to do is add on a tiny amount to prevent any attempt at evaluating the gamma function exactly at zero, or at one of the negative integers, round the result and I have a function that can handle r>n. Then I can have that elusive one line solution for the generation of the Pascal matrix.

Start Pascal( n );

return( icomb( row(j(n,n)) - 1, col(j(n,n)) - 1 ) );

finish;

print ( Pascal(12) ) [f=3.0];

As for utility of the modified function, I admit it is limited as I have been using the COMB function for some years and this is the first time I have tried using it with r>n, but my expectation was that it would perform like ICOMB above.

ICOMB may not be robust and only work with smaller n, and my original Pascal function contains 3n^2 unnecessary multiplications in its desperate attempt to retain 'elegance' while circumventing the invalid argument issues, so thanks to Rick for the alternative suggestions. Actually I prefer the shorter function with the loop rather than the fully vectorized version!

Registration is open! SAS is returning to Vegas for an AI and analytics experience like no other! Whether you're an executive, manager, end user or SAS partner, SAS Innovate is designed for everyone on your team. Register for just $495 by 12/31/2023.

**If you are interested in speaking, there is still time to submit a session idea. More details are posted on the website. **

Multiple Linear Regression in SAS

Learn how to run multiple linear regression models with and without interactions, presented by SAS user Alex Chaplin.

Find more tutorials on the SAS Users YouTube channel.