Way Cool: Linear Algebra in the Oracle Database 1
New to the Oracle Database 10g Release 2 is a hidden gem, the UTL_NLA package. This not very well known package (you don't get many hits for it in Google) brings linear algebra functionality to the Oracle Database. It makes the Oracle Database an even better platform for scientific and advanced analytics programming. Now it is possible to write performant matrix code in the database easily and avoid moving data around. Here is a brief description from the Oracle® Database Data Warehousing Guide 10g Release 2 (10.2):
Linear algebra is a branch of mathematics with a wide range of practical applications. Many areas have tasks that can be expressed using linear algebra, and here are some examples from several fields: statistics (multiple linear regression and principle components analysis), data mining (clustering and classification), bioinformatics (analysis of microarray data), operations research (supply chain and other optimization problems), econometrics (analysis of consumer demand data), and finance (asset allocation problems). Various libraries for linear algebra are freely available for anyone to use. Oracle's UTL_NLA package exposes matrix PL/SQL data types and wrapper PL/SQL subprograms for two of the most popular and robust of these libraries, BLAS and LAPACK.BLAS and LAPACK are probably the predominant linear algebra libraries out there. These libraries are extensively used by a large number of scientific programs and specialized tools.
Linear algebra depends on matrix manipulation. Performing matrix manipulation in PL/SQL in the past required inventing a matrix representation based on PL/SQL's native data types and then writing matrix manipulation routines from scratch. This required substantial programming effort and the performance of the resulting implementation was limited. If developers chose to send data to external packages for processing rather than create their own routines, data transfer back and forth could be time consuming. Using the UTL_NLA package lets data stay within Oracle, removes the programming effort, and delivers a fast implementation.
For developers, these libraries provide the building blocks for easily implementing a large number of advanced techniques. Take for example a toolbox like MATLAB, many of its capabilities are built on top of linear algebra primitives provided by packages like BLAS and LAPACK. Having these libraries in the database allow developers to write compact and ease to read code written using vector operations. Also, because these libraries have efficient and robust implementation of linear algebra operations, code using the UTL_NLA package inherent these qualities for free.
Besides scientific programming, Oracle's linear algebra support can also be used for business analysis. One example is multiple linear regression. The database ships with a multiple regression application built using the UTL_NLA package. This application is implemented in an object called OLS_Regression. Note that sample files for the OLS Regression object can be found in $ORACLE_HOME/plsql/demo. Take a look here for an example of how to use this functionality.
Another example of business analysis is solving a system of linear equations. In this post I give a couple of examples of how to solve a system of linear equations with UTL_NLA. In a follow up post I will show how to implement Principal Components Analysis (PCA) using the package.
Required Expertise, Limitations, and Usability
Before using the UTL_NLA package for development there are a couple of things to keep in mind. Oracle documentation states that developers using this package are expected to have a sound grasp of linear algebra in general and of the BLAS and LAPACK libraries in particular. I believe basic knowledge of linear algebra is enough if you are just trying to implement a well-known algorithm using this package. With respect to BLAS and LAPACK it is important to familiarize yourself with some basic concepts (e.g., matrix storage representation: column- or row-wise) and also to better understand some of the arguments the procedures in the package take. Besides the Oracle documentation some other useful references are: The Lapack Users' Guide, the BLAS and the LAPACK chapters in the in CRC Handbook of Linear Algebra.
The UTL_NLA package currently only supports matrices with up to 1,000,000 elements. For example, if we think of a table as a matrix, where table columns map to matrix columns and table rows to matrix rows, then for a table with 100 columns we can store up to 10,000 rows in a single matrix. It is useful to think in these terms because the number of rows is usually larger than the number of columns in a table. Furthermore, for many applications, we can obtain good results working on a sample of the data. This can be easily done in the database.
In order to use UTL_NLA, matrices have to be represented as either UTL_NLA_ARRAY_DBL or UTL_NLA_ARRAY_FLT. These types are PL/SQL VARRAY. However, many applications require data that resides in tables. It would be a nice addition to the package to have the ability to create a matrix from a query and to persist matrices to tables as well. This would alleviate the need for developers to code their own data read and write routines and increase usability. In the next post, along with the PCA example, I will include a couple of procedures to help with these tasks.
Solving Systems of Linear Equations
Systems of linear equations (see here for a less technical description) are of great importance in mathematics and its applications to areas of physical sciences, economics, engineering and many more. The goal in solving a system of linear equations is to find a set of values for the unknowns that satisfies all the equations in the system. Let me illustrate this with a couple of examples.
Example 1: Trip Planning (adapted from AlgebraLAB)
You are planning a 7 day trip to the East Coast. You estimate that it will cost $300 per day in Boston and $675 per day in New York City. Your total budget for the 7 days is $2850. How many days should you spend in each location?
This problem can be mapped to the following system of linear equations:
where x1 is the number of days in Boston and x2 is the number of days in New York City. x1 and x2 are the unknowns, the values we want to compute.The first equation requires that the total time be equal to 7 days. The second equation requires that the total amount spent in the trip to be equal to the available budget. In matrix form this system can be expressed as A*X = B where the matrices A, X, and B are as follows:
We can use the LAPACK_GESV procedure in UTL_NLA to solve this problem. This procedure computes the solution to a real system of linear equations A*X=B where A is an n by n matrix and X and B are n by 1 matrices. Here is a code snippet that solves this problem:
-- EXAMPLE 1: Trip PlanningThe above code returns:
DECLARE
A utl_nla_array_dbl := utl_nla_array_dbl(1, 300,
1, 675);
B utl_nla_array_dbl := utl_nla_array_dbl( 7,
2850);
ipiv utl_nla_array_int := utl_nla_array_int(0,0);
info integer;
BEGIN
UTL_NLA.LAPACK_GESV (
n => 2, -- A number of rows and columns
nrhs => 1, -- B number of columns
a => A, -- matrix A
lda => 2, -- max(1, n)
ipiv => ipiv, -- pivot indices (set to zeros)
b => B, -- matrix B
ldb => 2, -- ldb >= max(1,n)
info => info, -- operation status (0=sucess)
pack => 'C' -- how the matrices are stored
-- (C=column-wise)
);
dbms_output.put_line('TRIP PLANNING');
dbms_output.put_line('-------------');
dbms_output.put_line('info= '||info);
IF info=0 THEN
FOR i IN 1..B.count LOOP
dbms_output.put_line('x' || i ||'= ' || TO_CHAR(B(i),'99.99'));
END LOOP;
END IF;
END;
/
TRIP PLANNINGThe arrays A and B store, respectively, matrix A and B in column order. It only takes a single procedure to solve the problem. On exit, if the argument info = 0 (success), the procedure overwrites the array B with the n by 1 solution matrix X. For this example, the solution is x1=5 and x2=2.
-------------
info= 0
x1= 5.00
x2= 2.00
Example 2: BurgerRama Cartoon Dolls
(originally in the October 1991 edition of Mathematics Teacher - adapted from here)
Joan King is marketing director for the BurgerRama restaurant chain. BurgerRama has decided to have a cartoon-character doll made to sell at a premium price at participating BurgerRama locations. The company can choose from several different versions of the doll that sell at different prices. King’s problem is to decide which selling price will best suit the needs of BurgerRama’s customers and store managers. King has data (Table 1) from previous similar promotions to help her make a decision.
To solve this problem we need to proceed in two steps. First we need to estimate the supply and demand equations from the above data. Then we solve a system of linear equations to find the market equilibrium price where supply equals demand.
For the supply equation we want find a linear equation relating supply (S) to price (P) that fits the data in Table 1. Let write this equation as S = c1 P + c2, where c1 and c2 are the parameters we want to estimate. By replacing S and P in the supply equation with the values in Table 1 we obtain the following system of three linear equations:
In matrix form this system can be expressed as A*X = B where the matrices A, X, and B are as follows:
This type of system, with more equations (3) than unknowns (c1, c2) is called an overdetermined system. Solving this problem is the same as solving a multivariate linear regression problem.
We can use the procedure LAPACK_GELS to solve this system. The LAPACK_GELS procedure solves overdetermined and underdetermined real linear systems. The relevant code snippet is:
DECLAREThe above code returns:
A utl_nla_array_dbl;
B utl_nla_array_dbl;
ipiv utl_nla_array_int:= utl_nla_array_int(0,0,0);
info integer;
BEGIN
---------------------------------------
-- STEP 1a: SUPPLY
-- Find Supply equation S = c1*P + c2
A := utl_nla_array_dbl
(1, 2, 4,
1, 1, 1);
B := utl_nla_array_dbl
( 35,
130,
320);
UTL_NLA.LAPACK_GELS (
trans => 'N', -- transpose or normal problem
m => 3, -- A number of rows
n => 2, -- A number of columns
nrhs => 1, -- B number of columns
a => A, -- A matrix
lda => 3, -- max(1,m)
b => B, -- B matrix
ldb => 3, -- max(1,n,m)
info => info, -- operation status (0=sucess)
pack => 'C' -- how the matrices are stored
); --(C=column-wise)
dbms_output.put_line('SUPPLY EQUATION');
dbms_output.put_line('---------------');
dbms_output.put_line('info= '||info);
IF info=0 THEN
dbms_output.put_line('c1= ' || TO_CHAR(B(1),'999.99'));
dbms_output.put_line('c2= ' || TO_CHAR(B(2),'999.99'));
dbms_output.put_line('error= ' || TO_CHAR(B(3),'999.99'));
END IF;
END;
SUPPLY EQUATIONWe have just implemented multivariate linear regression using a single PL/SQL procedure call! On entering the procedure the array B contains the values for the matrix B above. On exiting the procedure, the first two elements of B are the values for c1 and c2, the coefficients for the supply equation. The third element is the residual sum of squares for the solution, that is, the sum of the squared differences between the values predicted by the solution for S and the actual values in the data. Replacing the obtained values for c1 and c2 in the supply equation we obtain: S = 95 P - 60.
---------------
info= 0
c1= 95.00
c2= -60.00
error= .00
Setting up a similar problem for the demand data gives a system with the same A matrix and a different B matrix (B=(530,400,140)). Solving this system of equations (see code at the end of the post) gives the following demand equation: D = -130 P + 600.
In order to find the market equilibrium price (step 2) we create a new system of linear equations combining the supply and demand equations with a new equation requiring that supply equals demand. The system looks like this:
The first two equations are, respectively, the supply and demand equations we obtained in step 1 above. The third equation is the market equilibrium condition (S=D). The matrix representation for the system is as follows:
The solution of this system of linear equations is S = D = 244 units and P = $3.20.
Here is the code for all the steps in this example:
-- EXAMPLE 2: BurgerRamaThe above code has only three procedure calls. It is even possible to solve steps 1a and 1b with a single call by combining the B matrices used in both steps into a single one. This would require only two procedure calls to solve Example 2.
DECLARE
A utl_nla_array_dbl;
B utl_nla_array_dbl;
ipiv utl_nla_array_int:= utl_nla_array_int(0,0,0);
info integer;
BEGIN
---------------------------------------
-- STEP 1a: SUPPLY
-- Find Supply equation S = c1*P + c2
A := utl_nla_array_dbl
(1, 2, 4,
1, 1, 1);
B := utl_nla_array_dbl
( 35,
130,
320);
UTL_NLA.LAPACK_GELS (
trans => 'N', -- transpose or normal problem
m => 3, -- A number of rows
n => 2, -- A number of columns
nrhs => 1, -- B number of columns
a => A, -- A matrix
lda => 3, -- max(1,m)
b => B, -- B matrix
ldb => 3, -- max(1,n,m)
info => info, -- operation status (0=sucess)
pack => 'C' -- how the matrices are stored
); --(C=column-wise)
dbms_output.put_line('SUPPLY EQUATION');
dbms_output.put_line('---------------');
dbms_output.put_line('info= '||info);
IF info=0 THEN
dbms_output.put_line('c1= ' || TO_CHAR(B(1),'999.99'));
dbms_output.put_line('c2= ' || TO_CHAR(B(2),'999.99'));
dbms_output.put_line('error= ' || TO_CHAR(B(3),'999.99'));
END IF;
---------------------------------------
-- STEP 1b: DEMAND
-- Find Demand equation D = c1*P + c2
-- The A matrix is the same as that for the
-- supply equation. Need to re-assign because
-- it was overwritten
A := utl_nla_array_dbl
(1, 2, 4,
1, 1, 1);
B := utl_nla_array_dbl
(530,
400,
140);
UTL_NLA.LAPACK_GELS (
trans => 'N', -- transpose or normal problem
m => 3, -- A number of rows
n => 2, -- A number of columns
nrhs => 1, -- B number of columns
a => A, -- A matrix
lda => 3, -- max(1,m)
b => B, -- B matrix
ldb => 3, -- max(1,n,m)
info => info, -- operation status (0=sucess)
pack => 'C' -- how the matrices are stored
); --(C=column-wise)
dbms_output.put_line('DEMAND EQUATION');
dbms_output.put_line('---------------');
dbms_output.put_line('info= '||info);
IF info=0 THEN
dbms_output.put_line('c1= ' || TO_CHAR(B(1),'999.99'));
dbms_output.put_line('c2= ' || TO_CHAR(B(2),'999.99'));
dbms_output.put_line('error= ' || TO_CHAR(B(3),'999.99'));
END IF;
---------------------------------------
-- STEP 2:
-- Find market equilibrium price
A := utl_nla_array_dbl
( 1, 0, 1,
0, 1, -1,
-95, 130, 0);
B := utl_nla_array_dbl
(-60,
660,
0);
UTL_NLA.LAPACK_GESV (
n => 3,
nrhs => 1,
a => A,
lda => 3,
ipiv => ipiv,
b => B,
ldb => 3,
info => info,
pack => 'C');
dbms_output.put_line('MARKET EQUILIBRIUM');
dbms_output.put_line('------------------');
dbms_output.put_line('info= '||info);
dbms_output.put_line('S = '||TO_CHAR(B(1),'999.99'));
dbms_output.put_line('D = '||TO_CHAR(B(2),'999.99'));
dbms_output.put_line('P = '||TO_CHAR(B(3),'999.99'));
END;
/
In the next post in this series I will show how to do Principal Components Analysis (PCA) using the UTL_NLA package.
Labels: Linear Algebra, UTL_NLA
Excellent stuff..thanks for sharing.
Posted by Anonymous | 5/05/2007 06:19:00 PM
Thanks Venkat. I hope to have a second post on UTL_NLA soon. It will cover Principal Component Analysis and its uses in visualization and search.
Posted by Marcos | 5/06/2007 11:36:00 AM
At last one clarifying article about a very powerful yet undiscovered feature of Oracle Thanks for sharing it with us. Please post more on this! If you have reccomended readings about this please share them with us! Thanks a lot.
Davide Moraschi
Posted by Anonymous | 5/23/2007 06:17:00 AM
Thanks Davide. I did look around for examples of how to use UTL_NLA and there is very little out there. The next post will cover PCA and touch on the use of Singular Value Decomposition (SVD). Very powerful features.
Posted by Marcos | 5/23/2007 07:10:00 AM
thanks a lot for the excellent coverage on utl_nla.
i'm trying to understand blas and lapack routines. it seems like one should know a great deal about linear algebra to understand.
if possible could you please suggest a good book or a reference where each of these routines are explained in layman's terms.
Posted by Anonymous | 7/09/2007 07:47:00 PM
Unfortunately I don't know of a book that explains the routines in layman's terms. The BLAS and LAPACK routines were designed to support scientific programming. So they kind of assume knowledge about the methods they implement. A good book on scientific programming that covers many of the methods implemented by these routine is Numerical Recipes in C (there are versions for other languages as well). This book has nice discussions on many useful methods as well as code. However, you can use the BLAS and LAPACK routines instead of the code in the book and just get the concepts and areas of applications from the book.
Posted by Marcos | 7/14/2007 01:47:00 AM
Very interesting undocumented features!
Is it possible to create a "utl_nla_array_dbl" data type dynamically from a select query instead of having to explicitly declare it like you do here:
A := utl_nla_array_dbl
(1, 2, 4,
1, 1, 1);
I want to retrieve these values from a table.
Thanks.
Posted by Anonymous | 8/21/2007 03:46:00 PM
Take a look at the procedures in my second post for reading and writing data from tables. In the case of reading you can actually specify a query. Here is a link to the post.
Posted by Marcos | 9/13/2007 07:59:00 PM
Hi Macro,
New to ODM, interesting stuffs, thanks a lot.
Get a question about OLS_Regression mentioned in your paragraph. My oracle is version 10g. Unfortunately, I can't find the OLS Regression object in my $ORACLE_HOME/plsql/demo. And an error was generated when trying to run the OLS_Regression example in the 'here' link. Could you please shed me some light on how OLS Regression can be used? Many thanks.
Posted by Anonymous | 9/20/2007 11:04:00 PM
I believe that the demo requires you to install some content from the Oracle RDBMS companion CD. This is the case for the data mining demos. See this link for instructions for the data mining demos. Follow similar steps for installing the sample files for UTL_NLA.
Posted by Marcos | 11/15/2007 03:04:00 PM
Hi Marco,
Great post. It gave me a good guide on how to solve linear equations.
However, I can't seem to figure out how to solve "minimize" or "maximize" object functions.
An example of what I'm trying to solve is found in the link http://people.hofstra.edu/Stefan_Waner/Realworld/simplex.html . I'm trying the solve the "Example" problem using UTL_NLA.LAPACK_GELS
LAPACK_GELS is the only procedure I found that accepts A as m x n matrix
Here's the actual code I tried to use :
DECLARE
A utl_nla_array_dbl := utl_nla_array_dbl(1 ,2 ,0 ,-0.5 -- x
,1 ,1 ,-1 ,-3 -- y
,1 ,-1 ,0 ,-1 -- z
,1 ,-1 ,1 ,-4 -- w
,1 ,0 ,0 ,0 -- s1
,0 ,1 ,0 ,0 -- s2
,0 ,0 ,1 ,0 -- s3
,0 ,0 ,0 ,1 -- p
);
B utl_nla_array_dbl := utl_nla_array_dbl(40, 10, 10, 0);
ipiv utl_nla_array_int := utl_nla_array_int( 0, 0, 0, 0, 0, 0, 0, 0);
info integer;
BEGIN
UTL_NLA.LAPACK_GELS(
trans => 'T', -- CHARACTER = 'N': The linear system involves A. CHARACTER = 'T': The linear system involves A**T.
m => 4, -- The number of rows of the matrix a. M >= 0.
n => 8, -- The number of columns of the matrix a. N >= 0.
nrhs => 1, -- The number of right-hand sides, which is the number of columns of the matrix band x.nrhs >= 0.
a => A, -- matrix A
lda => 4, -- The leading dimension of the array A. lda >= max(1,m).
b => B, -- matrix B
ldb => 4, -- The leading dimension of the array b. ldb >= max(1,m,n)
info => info, -- operation status (0=sucess)
pack => 'C' -- how the matrices are stored
-- (C=column-wise)
);
dbms_output.put_line('SAMPLE');
dbms_output.put_line('-------------');
dbms_output.put_line('info= '||info);
IF info=0 THEN
FOR i IN 1..B.count LOOP
dbms_output.put_line('var' || i ||'= ' || TO_CHAR(B(i),'999999.99999999'));
END LOOP;
END IF;
END;
/
The ouput is:
SAMPLE
-------------
info= 0
var1= 12.99193724
var2= 8.96927435
var3= 3.19241665
var4= 1.63870124
Which is no way near the solution found in the link I gave above which is :
Optimal Solution: p = 115; x = 10, y = 10, z = 0, w = 20
Hope you can help :)
Thanks,
Henry Wu
Posted by Unknown | 3/29/2008 08:54:00 PM
Hi Henry,
The problem the link pointed to is an example of linear programming (optimization). In this case the constraints are not equalities but inequalities (e.g., <= or >=). The UTL_NLA package does not have support for this type of problem.
Posted by Marcos | 3/31/2008 09:26:00 AM
Thanks for the post. It is really good. However, I have one query. What if we want to work with a mtrix with more than 1mil elements. We have a need to cater for a matrix that is 3000 x 3000 elements.
Is there any way to do it still using the package or it just can't be done and will have to fall back to traditional coding.
Posted by Anonymous | 5/07/2008 02:28:00 AM
The UTL_NLA package only supports matrices with up to 1M elements. Depending on what you would like to do there workarounds that can be used. Can you give some details about your use cases?
Posted by Marcos | 5/07/2008 08:08:00 AM
Hi Marcos!
Could you give me an example how to inverse a matrix using UTL_NLA package? Which procedure should I use to get an inverted matrix?
For example:
v_A utl_nla_array_dbl:=utl_nla_array_dbl(5, 153, 352,
153, 5899, 9697,
352, 9697, 26086);
Thanks!
Mikka
Posted by Anonymous | 7/16/2008 11:44:00 AM
Hi Mika,
You can invert a matrix solving a system of linear equation AX = B like the ones I described in the post but setting B to the identity matrix.
For example, the following code inverts the matrix you gave in your question:
DECLARE
A utl_nla_array_dbl := utl_nla_array_dbl(
5, 153, 352,
153, 5899, 9697,
352, 9697, 26086);
B utl_nla_array_dbl := utl_nla_array_dbl(
1, 0, 0,
0, 1, 0,
0, 0, 1);
ipiv utl_nla_array_int := utl_nla_array_int(0,0);
info integer;
n NUMBER := 3;
i NUMBER;
j NUMBER;
BEGIN
UTL_NLA.LAPACK_GESV (
n => n, -- A number of rows and columns
nrhs => n, -- B number of columns
a => A, -- matrix A
lda => n, -- max(1, n)
ipiv => ipiv, -- pivot indices (set to zeros)
b => B, -- matrix B
ldb => n, -- ldb >= max(1,n)
info => info, -- operation status (0=sucess)
pack => 'R' -- how the matrices are stored
-- (C=column-wise)
);
dbms_output.put_line('info= '||info);
dbms_output.put_line('inv(A)');
dbms_output.put_line('-------------');
IF info=0 THEN
FOR l IN 1..B.count LOOP
i := ceil(l/n);
j := l-(i-1)*n;
dbms_output.put_line('x[' || i ||']['||j||']= ' || TO_CHAR(B(l),'99.9999'));
END LOOP;
END IF;
END;
/
info= 0
inv(A)
-------------
x[1][1]= 27.5307
x[1][2]= -.2658
x[1][3]= -.2727
x[2][1]= -.2658
x[2][2]= .0030
x[2][3]= .0025
x[3][1]= -.2727
x[3][2]= .0025
x[3][3]= .0028
Posted by Marcos | 7/29/2008 08:31:00 AM
Hi Marcos!
Thanks for your example, it helped me. I've tried your example with a bigger matrix (n=124) and variable info was 114 after execution and the result was not right. I've used an external function wrote in JAVA to determine the inverse matrix and Java version gave right result. I suppose there are limitations in Oracle version. Am I right?
Thaks!
Mikka
Posted by Anonymous | 7/30/2008 09:25:00 AM
Hi Mikka,
The UTL_NLA package does have some limitations on the size of the matrices it supports. However 124 is fine. The problem seems to be related with the method used to solve the problem. There are many different methods that you can pick depending on the special nature of the matrix. The one I used in the code uses LU decomposition. It seems that this decomposition fails for your example. I would suggest using the more general procedure LAPACK_GELS. This one uses QR or LQ decompositions as needed. In the code below I replaced the solver with LAPACK_GELS.
DECLARE
A utl_nla_array_dbl := utl_nla_array_dbl(
5, 153, 352,
153, 5899, 9697,
352, 9697, 26086);
B utl_nla_array_dbl := utl_nla_array_dbl(
1, 0, 0,
0, 1, 0,
0, 0, 1);
ipiv utl_nla_array_int := utl_nla_array_int(0,0);
info integer;
n NUMBER := 3;
i NUMBER;
j NUMBER;
BEGIN
UTL_NLA.LAPACK_GELS (
trans => 'N', -- solve for A instead of A'
m => n, -- A number of rows
n => n, -- A number of columns
nrhs => n, -- B number of columns
a => A, -- matrix A
lda => n, -- max(1, m)
b => B, -- matrix B
ldb => n, -- ldb >= max(1, m, n)
info => info, -- operation status (0=sucess)
pack => 'R' -- how the matrices are stored
-- (C=column-wise)
);
dbms_output.put_line('inv(A)');
dbms_output.put_line('-------------');
dbms_output.put_line('info= '||info);
IF info=0 THEN
FOR l IN 1..B.count LOOP
i := ceil(l/n);
j := l-(i-1)*n;
dbms_output.put_line('x[' || i ||']['||j||']= ' || TO_CHAR(B(l),'99.9999'));
END LOOP;
END IF;
END;
/
info= 0
x[1][1]= 27.5307
x[1][2]= -.2658
x[1][3]= -.2727
x[2][1]= -.2658
x[2][2]= .0030
x[2][3]= .0025
x[3][1]= -.2727
x[3][2]= .0025
x[3][3]= .0028
Posted by Marcos | 7/30/2008 01:05:00 PM
Hi Marcos!
I tried your 2nd example with my bigger matrix and info parameter was 0 but the result was not right. I don't know why. I stored the matrix elemets in a table both Java and Oracle version and I got totally different results. With utl_nla I got much bigger elements than with Java version...Do you have any idea? I think with smaller matrix Oracle version works fine but with bigger matrix it dosn't give the right result.
Thanks!
Mikka
Posted by Anonymous | 7/31/2008 05:16:00 AM
Mikka,
Oracle should do fine with larger matrices as well (as long as it has less than one million elements). The UTL_NLA package uses LAPACK routines. Those are very robust and the basis for linear algebra packages out there. If you could post your code and the data for the matrix in the ODM forum (link) I can take a look at it.
Posted by Marcos | 8/01/2008 08:33:00 AM
do you have an example for multiple linear regression. thanks.
Posted by Anonymous | 6/02/2009 10:28:00 AM
I see Oracle documentation for BLAS/LAPACK wrappers, but no documentation for utl_nla_array_dbl etc.
Where is the documentation for elementary procedures on utl_nla_array_dbl? For example, is there a (brief) way to return the k'th column of a matrix A?
Posted by Peter Cotton | 11/19/2009 07:05:00 PM