Thread: multiple template specialized types

  1. #1
    Registered User
    Join Date
    Feb 2012
    Location
    Ottawa
    Posts
    6

    multiple template specialized types

    I have a templated sparse matrix class:
    Code:
    template <index_t, scalar> sparse;
    and a templated matrix array class:
    Code:
    template <index_t, scalar, matrix_t> sparse_array
    How do I create another matrix array type, specializing only the matrix type, matrix_t? Something like this:
    Code:
    template<index_t, scalar>
    typedef sparse_array<index_t, scalar, sparse<index_t, scalar>> sparse arr;
    only I know this doesn't work (I tried it), but you get the basic idea, I hope...

  2. #2
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    O_o

    Yea, this isn't going to work either. Well, not without quite a bit of work.

    You can partially specialize a template easily (That's a hint; search it.), but from the context provided, it seems more that you want template typedefs which aren't a thing (in portable C++98).

    Just out of curiosity, what is `index_t' in this context?

    Anyway, you need to start posting examples that are complete and meaningful. Your examples don't work for the simple reason that the examples aren't valid C++, but with so much missing we can only speculate on what changes may be necessary. None of us want to play guessing games. Well, not with you. I think a few of the regulars have young children.

    Soma

  3. #3
    Registered User
    Join Date
    Feb 2012
    Location
    Ottawa
    Posts
    6
    Quote Originally Posted by phantomotap View Post
    O_o

    You can partially specialize a template easily (That's a hint; search it.), but from the context provided, it seems more that you want template typedefs which aren't a thing (in portable C++98).
    I don't care if it uses typedef's or not. I want one of the template arguments to be specialized and the others not. And I don't want to declare a new class in the proces...

    Quote Originally Posted by phantomotap View Post
    Just out of curiosity, what is `index_t' in this context?
    A matrix has two types of parameters: a real or complex type for holding the actual variables, which are then dependent on an integer type to index them...

    Quote Originally Posted by phantomotap View Post
    Anyway, you need to start posting examples that are complete and meaningful. Your examples don't work for the simple reason that the examples aren't valid C++, but with so much missing we can only speculate on what changes may be necessary. None of us want to play guessing games. Well, not with you. I think a few of the regulars have young children.
    I'm not sure I buy that. I'm simply omitting anything not immediately germain to the problem. To post the entire source and explain its rationale would take more space than I have here. The entire source can be found here:
    SourceForge.net Repository - [msci] Index of /libpetey/sparse
    Perhaps you'd like to become a developer?

    The rational for what I'm doing (creating a calculator for manipulating large, sparse matrices) can be found here:
    http://peteysoft.org/publications.html
    under the publication entitled "Principal component proxy tracer analysis."

    Briefly, I submitted a paper about dynamically interpolating sparse satellite measurements (not to be confused with the sparse matrices doing the interpolation) of trace substances by converting the tracer dynamics into an array of sparse matrices. These I decompose into the largest principal components and correlate them with the satellite measurements.

    The reviewers wanted to know more about how to determine the right number of principal components. To do this properly, I would have to understand more about how the method works, which means manipulating the matrics that represent the tracer dynamics in various ways. In order to conduct a series of numerical experiments, I decided to create a calculator for large matrices using yacc. I already had a templated sparse matrix class that worked quite well, but needed the other two types. To reduce the amount of yacc code written, I decided it would be easiest to use polymorphism to work transparently between all three types.

    I'm not sure this makes it any clearer...

  4. #4
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    To post complete and meaningful code doesn't mean you need to post your whole project. Post the smallest piece of code that demonstrates your problem and/or question. From what you've posted I don't know what you actually want.

    Template specialization is about creating a specialized IMPLEMENTATION for specific types, not about saving keystrokes (which is all you're trying to do as far as I can tell).

    You mention polymorphism in your second post, which is a completely separate thing.

  5. #5
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    I'm not sure I buy that.
    Your opinion of the requirements I demand before I will offer you more help is irrelevant.

    You are well within your rights to ignore those requirements; I'm just not going to spend any more effort to help you.

    And just so as you know, for the future, a complete and meaningful example tells us the most important part of solving an implementation error: it tells us how you are trying to implement something. Without that, we would literally be guessing. But it isn't the same thing as a source dump.

    You've told us how you'd like to do something. You've told us why you'd like to do it. You've even told use what it is for. That doesn't tell us what you've actually done.

    Perhaps you'd like to become a developer?
    It is GPL so I threw it on the stack. We'll see what happens when I get to it.

    Soma

  6. #6
    Registered User
    Join Date
    Feb 2012
    Location
    Ottawa
    Posts
    6
    Maybe I should start over, combining this query with the previous one. Here is what I have so far (and it's actually starting to look like it's going to work):

    Code:
    template <class index_t, class scalar>
    class matrix_base {
      ...
      virtual matrix_base<index_t, scalar> * mat_mult(full_matrix<index_t, scalar>)=0;  
      virtual matrix_base<index_t, scalar> * mat_mult(sparse<index_t, scalar>)=0;
      virtual matrix_base<index_t, scalar> * mat_mult(sparse_arr<index_t, scalar>)=0;
    };
    
    //a sparse matrix class:
    template <class index_t, class scalar>
    class sparse:public matrix_base<index_t, scalar> {
      ...
      virtual matrix_base<index_t, scalar> * mat_mult(full_matrix<index_t, scalar>);  
      virtual matrix_base<index_t, scalar> * mat_mult(sparse<index_t, scalar>);
      virtual matrix_base<index_t, scalar> * mat_mult(sparse_arr<index_t, scalar>);
    };
    
    //a class containing an array of sparse matrices:
    template <class index_t, class scalar>
    class sparse_arr:public matrix_base<index_t, scalar> {
      ...
      virtual matrix_base<index_t, scalar> * mat_mult(full_matrix<index_t, scalar>);  
      virtual matrix_base<index_t, scalar> * mat_mult(sparse<index_t, scalar>);
      virtual matrix_base<index_t, scalar> * mat_mult(sparse_arr<index_t, scalar>);
    };
    
    //full matrix class follows from the first two children...
    The sparse array class presents a problem, however, since it actually has three template parameters:

    Code:
    template<index_t, scalar, matrix_t>
    class sparse_array:public matrix_base<index_t, scalar> {
      matrix_t *array_of_sparse_matrices;
      int number_of_sparse_matrices;
     ...
    };
    So I need a way to squish the third template parameter down to the other two using sparse<index_t, scalar> for matrix_t . I need to do this before the other two classes can use the sparse array class since C++ doesn't allow templated virtual functions and I don't want the extra almost-useless template parameter dangling off the other two classes.

    This is what I'm trying, but I don't know if it compiles yet because I need to update the makefile and get rid of all the other compilation errors first:
    Code:
    template <index_t, scalar>
    class sparse_arr:public sparse_array<index_t, scalar, sparse<index_t, scalar>> {};
    Last edited by petey; 02-23-2012 at 12:35 AM. Reason: errors in original post

  7. #7
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    My criticism from the other thread still applies to those classes.

    So I need a way to squish the third template parameter down to the other two using sparse<index_t, scalar> for matrix_t .
    No. You don't. You need to use the features C++ offers correctly.

    Code:
    template<index_t, scalar, matrix_t>
    class sparse_array:public matrix_base<index_t, scalar>
    This isn't valid; if you copied this from source, this is one area causing you problems.

    Code:
    template <index_t, scalar>
    class sparse_arr:public sparse_array<index_t, scalar, sparse<index_t, scalar>> {};
    This also isn't valid, but the idea of using a second class to separately default template parameters is certainly sound.

    However, from the sound of it, you only want to provide a default "value" for a template parameter. Again, search engines are a girls best friend, but it works almost exactly like default values for normal parameters.

    Soma

  8. #8
    Registered User
    Join Date
    Feb 2012
    Location
    Ottawa
    Posts
    6
    The problem as I see it is that C++ opens up such a bewildering array of possibilities that it really is impossible to tell what is "valid" and what isn't. The language contains syntax for both inheritance and templates and as far as I can see, at the moment they do not interoperate all that well. It seems to me you ought to be able to combine the two to have a whole array of related types that are all interoperable, but I realize it's not that simple. It is easy to see generalizations of the current scheme and wonder, well, "why can't I do that??" I don't know which generalizations work and which don't. That's why I'm using the C-board. Most of the stuff on templates and polymorphism I see on the net deals with very basic stuff. This more advanced stuff is rarely covered and if it is, it's difficult to search for because most of the searches I do just come up with the more basic stuff. It should be clear from the code that I'm writing, however false, what it is I am trying to do...

  9. #9
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    ^_^

    C++ is ugly and bewildering. I can't fault you for thinking that.

    Again, how you are trying to do something (i.e. the code) is different from the idea being approached (e.g. sorting) which is still different from the way you are approaching it (e.g. quicksort).

    Your code has issues. Fixing the "how" (the code) will help you understand problems with the approach (trying to get the compiler to generate a specific implementation of an interface to handle two abstract things). I don't care if you like that comment. That is the nature of the thing. I can't help you solve that problem. You'll have to experiment with C++ until you understand why that approach is never going to work.

    I've known what you were trying to do within a couple minutes of seeing your first thread. (I just didn't know how you had tried to approach a solution. That's the reason I needed more from you. For all I knew you were close to a solution and only needed a little help.) At the simplest, it is a dispatch problem (the idea). C++ doesn't directly support any form of multiple dispatch. If you want multiplication of a sparse matrix and a sparse matrix to be implemented differently than the multiplication of a matrix and a matrix you will have to do the work (the how). You can use inheritance based examination (as I know you realize); you can drop inheritance and use simple overloaded functions (as close as C++ gets to native multiple dispatch); you can use template classes; you can use expression templates; you can use any means to rig C++ with multiple dispatch you understand (the approach). It is your job to do it because C++ simply is not going to do it for you. Ever. All the meta-programming and libraries in the world will only make it easier, but C++ isn't going to do it all by itself.

    I've told you many things to search for before this post and now many more. I'm not going to hold your hand every step of the way. The simple fact is, you are trying to get C++ to generate the collision (the multiplication function needing multiple dispatch with n=2) without jumping through all the necessary hoops. I'm sorry, but that is literally never going to work.

    If you don't want to do the work you can try searching out other libraries that can do this for you.

    *shrug*

    All that said, other languages do support multiple dispatch. If you don't like what C++ has to offer, check out other languages. In some languages this really would be as simple as writing the different multiplication functions.

    Soma

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 6
    Last Post: 01-26-2010, 09:04 AM
  2. Replies: 3
    Last Post: 10-08-2009, 01:05 PM
  3. mixing non-specialized and specialized templates
    By m37h0d in forum C++ Programming
    Replies: 6
    Last Post: 12-05-2008, 04:11 PM
  4. Replies: 4
    Last Post: 11-01-2006, 02:23 PM
  5. Error compiling a specialized template in Devc++
    By Kylecito in forum C++ Programming
    Replies: 7
    Last Post: 02-28-2006, 07:15 PM

Tags for this Thread