This project has moved. For the latest updates, please go here.

Matrix vs DenseMatrix

Apr 5, 2011 at 6:07 PM

Hi,

In my previous implementation with Iridium I used matrices a lot, which I would define by

Matrix M = new Matrix(SampleSize, nvar);

Now I can't seem to call that anymore. Am I supposed to be using DenseMatrix instead ? Is there a conceptual difference between the two ?

Also, at a later stage I need to do a matrix multiplication between a DenseMatrix and the result of a Cholesky decomposition, and get the following error : Cannot implicitly convert type 'MathNet.Numerics.LinearAlgebra.Generic.Matrix<double>' to 'MathNet.Numerics.LinearAlgebra.Double.DenseMatrix'. An explicit conversion exists (are you missing a cast?).

Thanks a lot for your help on this!

Apr 6, 2011 at 10:50 AM

Hi,

I am a new comer exploring the use of the Numerics library.  I also immediately come to a similar problem, to illustrate:

DenseMatrix foo = new DenseMatrix (5,5,2.34);

DenseMatrix tmp = foo.Inverse();     // gets the compiler error message you got

The trouble is that the Inverse method is inherited and only returns a generic type Matrix<double> instead of the same type (DenseMatrix) as foo, which is a reasonable expectation I think.  To get round that, explicit casting (rather ugly and a coding burden) is needed:

DenseMatrix tmp = (DenseMatrix) foo.Inverse();

I think the library should be improved in this respect.

Apr 6, 2011 at 11:10 AM

an option is to not to declare variables as DenseMatrix but as Matrix<double>.

Matrix<double> foo = new DenseMatrix (5,5,2.34);

Matrix<double> tmp = foo.Inverse();

I usually just use var

var foo = new DenseMatrix (5,5,2.34);

var tmp = foo.Inverse();

 

Apr 6, 2011 at 11:14 AM

> Is there a conceptual difference between the two ?

In numerics, we have several different type of matrices: dense, sparse, and diagonal (and probably more types in the future). Matrix is an abstract class the contains the common implementation of the different types.

Apr 6, 2011 at 12:02 PM

Thanks for the reply.  The example I used is a simplification, foo.Inverse() could be part of an expression such as (x * foo.Inverse()) where x is of type DenseVector. The library has no problem of multiplying a DenseVector with a DenseMatrix (returning a DenseVector), but fails for (DenseVector * Matrix<double>) and the example expression would not compile.

The option suggested also seems to defeat the rationale for more specialised classes (DenseMatrix etc.).

Apr 6, 2011 at 12:08 PM

Hmm, that should work. I'll look into to it.

>The option suggested also seems to defeat the rationale for more specialised classes (DenseMatrix etc.).

Why? 

Apr 6, 2011 at 12:15 PM

Actually

var y = x * foo.Inverse() ;  // works

but

y = x * foo.Inverse();  // fails, y is a system object rather than a local variable and is of type DenseVector

 

Apr 6, 2011 at 12:22 PM
Edited Apr 6, 2011 at 12:22 PM

How are you declaring y?

In cases where var doesn't work (such as when you assign objects to an existing variable declaration), you should declare them as Matrix<double> or Vector<double>. Never declare them as a specialized type. Does using base classes for variable declarations  work?

Apr 6, 2011 at 12:41 PM
cuda wrote:

How are you declaring y?

In cases where var doesn't work (such as when you assign objects to an existing variable declaration), you should declare them as Matrix<double> or Vector<double>. Never declare them as a specialized type. Does using base classes for variable declarations  work?


y is declared as DenseVector y

I didn't know that the Numerics library design expects variables to be declared using the base classes. That is not my normal coding style, but it is useful to know what is expected in how the library is used, thanks.  I can see that you can instantiate using a specialised class, i.e. Vector<double> y = new DenseVector (m); however in general, when several levels of inheritance are used, how does the user know which base level to use for declaration?

In this case, I think the specialised class DenseMatrix should have overriden the inherited Inverse() method to return a DenseMatrix - very simple to implement.

Apr 6, 2011 at 12:54 PM
Edited Apr 6, 2011 at 1:05 PM

>how does the user know which base level to use for declaration?
Always use the top the level, in this case Matrix<double> or Vector<double>. 

>In this case, I think the specialised class DenseMatrix should have overriden the inherited Inverse() method to return a DenseMatrix - very simple to implement.

DenseMatrix does override Inverse, but since the base class Matrix<T> returns a Matrix<T> we cannot change the method signature to return a DenseMatrix (even though the DenseMatrix implementation actually does so) - unless we use the new keyword or introduce interfaces and use explicit interface implementation.

Apr 6, 2011 at 2:04 PM
cuda wrote:

>how does the user know which base level to use for declaration?
Always use the top the level, in this case Matrix<double> or Vector<double>. 

>In this case, I think the specialised class DenseMatrix should have overriden the inherited Inverse() method to return a DenseMatrix - very simple to implement.

DenseMatrix does override Inverse, but since the base class Matrix<T> returns a Matrix<T> we cannot change the method signature to return a DenseMatrix (even though the DenseMatrix implementation actually does so) - unless we use the new keyword or introduce interfaces and use explicit interface implementation.


Thanks for the explanation.

Apr 8, 2011 at 12:20 PM

Hi,

have a sme prob with DenseMatrix....

I have two different matrix like this

 

var

D = new DenseMatrix(3); var MDelta = new DenseMatrix(3); 

 

Then I do some calculations and need to loop.

So I got a prob when I say

for (int

i = 0; i < N; i++)

calculation of D

 

MDelta = D * MDelta;

Error is the same like in the first post.

Thanks for help.

Apr 8, 2011 at 12:26 PM

Hi,

For beta 1, try:

Matrix<double> D = new DenseMatrix(3); 
Matrix<double> MDelta = new DenseMatrix(3); 
 
for (inti = 0; i < N; i++){
   ...
   MDelta = D * MDelta;
}

your original code should work in the latest releases, since we changed the operator overloads to return DenseMatrix rather than Matrix<T>. 

Apr 8, 2011 at 12:36 PM

where can I find the last release??

Apr 8, 2011 at 12:41 PM

"Source Code" -> "Latest Version" -> Download

Then build the project.

Apr 8, 2011 at 1:01 PM

ok downloaded...what do you mean by "build the project"...

sorry but I'm new to the prog-world... :-)

Apr 8, 2011 at 1:08 PM

no problem. Open ./src/MathNet.Numerics.sln in VS2010 and then click Build->Build Solution. The new DLL will be in a sub-directory under out.

Apr 8, 2011 at 1:34 PM

thanks for helping but it doesn't work.

My prob is that now I can't finde the MathNet.Numerics.dll  so where to reference at?

in the lib folder I have something like Moq,NUnit,NUnit.Silverlight....

If I go the way you describe I got an error like Fsharp project...Is it because I just have C#2010 Express??

Apr 8, 2011 at 1:49 PM

So you cannot open the solution at all in C# 2010 Express?

Apr 8, 2011 at 1:59 PM

I can but with lot of errors becaus it says it is a fsharp file...

I think the prob is the MathNet.Numerics.sln is not recognized as a C# file...

It says unrecognized version....don't know.

Apr 8, 2011 at 2:02 PM

can you right click on the numerics project and select build. Does that project build?

Apr 8, 2011 at 2:17 PM
Edited Apr 8, 2011 at 2:41 PM

no 21 Errors...

and by the way you solution with the matrix does not work as well

error " the non generic Type....cannot be used with type argument"...

 --->sorry your way works but still have the other prob...

Apr 8, 2011 at 3:03 PM

OK. Are the errors related to the T4 templates? Could you paste them here?

Apr 8, 2011 at 10:55 PM

> If I go the way you describe I got an error like Fsharp project...Is it because I just have C#2010 Express??

TTR, I wonder if you were building the entire solution. When you open the solution, you should see in the solution explorer window that the solution consists of many projects. Just select the one that yields the dll required and right click to build.  I use VS 2010 Professional, the Silverlight project does not build for me, but I don't need Silverlight and therefore did not have to bother sorting it out. Likewise, you don't need to bother any other projects that don't build for you.  I don't have my work computer with me and therefore I can't tell you precisely which project gives the dll you need and in which folder it can be found - but you should be able to work them out easily - and I was able to build and reference the latest dll.  Hope I am talking sense, if not, please excuse me!

Apr 8, 2011 at 11:32 PM

I was able to get it to compile with C# 2010 express earlier this week. Here's the steps I took:

1. Download the source code and extract it somewhere (I'm sure you did this already!)

2. Use Explorer to navigate to src/Numerics/Algorithms/LinearAlgebra. For each file in this folder that has a .include suffix, right click->properties->Unblock (this might be only needed for Win7). Win7 by default blocks these files from being executed for security purposes.

3. Open the solution and ignore the errors (can't open F#/Silverlight projects, version not supported, etc.)

4. Transform the T4 templates in the Numerics project. IIRC this button is at the top of the Solution Explorer window, I can't remember if its exactly the same in express. If not, you can manually do it by right-clicking all the .tt files in the Numerics project. Ensure they all complete successfully (should be in the Output window)

5. Right-click Numerics project -> Build

6. If build succeeded you will have the .dll in the output folder.

Hopefully that helps.

Apr 12, 2011 at 11:40 AM

Gents...thank you so much for your help!

I followed kyon's instructions and now it works. :-)

But I have another one...how can I directlly asigne values to a matrix M let's say...

Matrix<double> M = new DenseMatrix(3);

 I know want the matrix M to be (1,2,3,4,5,6,7,8,9) f.e.

 

 

 

Thnaks

Coordinator
Apr 12, 2011 at 12:06 PM
Matrix<double> m = new DenseMatrix(2, 3, new [] {1.1, 2.1, 1.2, 2.2, 1.3, 2.3});

creates

1.1 1.2 1.3
2.1 2.2 2.3

Hope that helps,
Chris

Apr 12, 2011 at 12:45 PM

Yes,thanks a lot!!

 

Jun 22, 2011 at 7:28 PM

Hi,

 

I want ot multip. a matrix and a vector but it doesn't work.

I guesse some typ error on my side...

I have this

Vector<double> d_V = new DenseVector(m);

 

thanks

 

 

 Matrix<double> MDelta = new DenseMatrix(m);

MDelta=d_V*MDelta;

 

Coordinator
Jun 22, 2011 at 8:57 PM

That's because d_v * MDelta is a vector and not a matrix.

var x = d_V * MDelta;
should work fine.

Jun 28, 2011 at 4:10 PM
Edited Jun 28, 2011 at 4:11 PM

Hi Chris,

I'm a beginner with C# programming so can you please show me how to initialize the matrix with complex numbers too?

Matrix<double> m = new DenseMatrix(2, 3, new [] {1.1, 2.1, 1.2, 2.2, 1.3, 2.3}); -> complex entries

 

Thx

Coordinator
Jun 28, 2011 at 4:24 PM

Something like this

            int N = 5;
            Matrix<Complex> A = new MathNet.Numerics.LinearAlgebra.Complex.DenseMatrix(m);
            for (int i = 0; i < N; i++)
            {
                for (int j = 0; j < N; j++)
                {
                    A[i, j] = new Complex(1.0, 1.0);
                }
            }

Jun 28, 2011 at 5:09 PM

Hi 

I was hoping for a way to initialize the matrix at the construction time like in the other example (Matrix<double> m = new DenseMatrix(2, 3, new [] {1.1, 2.1, 1.2, 2.2, 1.3, 2.3});)

 

Thanks!


Jun 28, 2011 at 5:26 PM

If they are all reals, then this will work (coverts the reals to complex):

var m = new DenseMatrix(2, 3, new Complex[] {1.1, 2.1, 1.2, 2.2, 1.3, 2.3});

else

var m = new DenseMatrix(2, 3, new [] {new Complex(1.1,1), new Complex(2.1, 1), new Complex(1.2, 1),new Complex( 2.2, 1), new Complex(1.3, 1), new Complex(2.3, 1)});

Jul 18, 2011 at 9:56 PM

Hello everyone,

It seems that I have the same problem than TTR had before.

I manage to put the .dll in the references and to compute my project, but when I try to create the object.

Vector<double> rVector = new DenseVector(n);

I get the error

Error 1 The non-generic type 'MathNet.Numerics.LinearAlgebra.Double.Vector' cannot be used with type arguments.

Can you please help me with this?

Coordinator
Jul 19, 2011 at 2:09 PM

Did you add

using MathNet.Numerics.LinearAlgebra.Generic;
at the top of your file?

Jul 19, 2011 at 2:54 PM

No, I had

using MathNet.Numerics.LinearAlgebra.Double;

It works fine now, thank you!

Nov 13, 2013 at 8:47 AM
Hi,

I am very new to .net and math.net.
I have a curiosity that would help me understand the some design choices:

Why .Inverse() and .Transpose() have not been passed along to the specialized classes through inheritance?

Thank you.
Coordinator
Nov 14, 2013 at 10:31 PM
I'm not sure I understand your question. Both Inverse and Transpose are defined in the generic base class Matrix<T> and thus are automatically inherited by all sub-classes (even though some override them for performance reasons). Maybe you can elaborate?

Thanks,
Christoph