1

Math.net has ToString() implementations for most data collections. When used in classes these need to be overridden. I know how to do this for one variable, but how to make it generic for all variables of the same type?

My class definition with one variable ToString() override:

public class Network
{
    public Matrix<double> Win { get; set; }         // network input matrix
    public Matrix<double> Wres { get; set; }        // network reservoir matrix
    public Matrix<double> Wout { get; set; }        // network output matrix

    // constructor
    public Network(Matrix<double> Winput, Matrix<double> Wreservoir, Matrix<double> Woutput)
    {
        Win = Winput;
        Wres = Wreservoir;
        Wout = Woutput;
    }

    public override string ToString()
    {
        return Win.ToString();
    }
}

This works on Win with a call like Console.WriteLine(network.Win.ToString()); but how to output the other matrices Wres, Wout (with different dimensions)? I have tried to create three overrides but that doesn't work as the compiler complains:

already defines a member called 'ToString' with the same parameter types

and besides, I am sure there must be a more generic and elegant way to do this.

Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
jdelange
  • 763
  • 2
  • 10
  • 22
  • Do you want one method that converts alle three matrices to a string representation? You could just return that inside your overridden ToString method. – Lars Kristensen Nov 21 '15 at 11:58
  • Lars, I want to be able to output any of the three matrices with a `WriteLine` statement as shown in my question. Can you show / explain what you are suggesting? – jdelange Nov 21 '15 at 12:06

2 Answers2

2

You've already created each Matrix as a public property in the Network class, so you can simply access them when you need to.

Network network = new Network(mInput, mResevoir, mOutput);

Console.WriteLine(network.Win);
Console.WriteLine(network.Wres);
Console.WriteLine(network.Wout);

Edit: I just realized that the properties also have a public set method. If you don't want the properties to be changed after the Network variable has been created, you can modify the setters to be private, so the values can only be se from within the class.

public class Network
{           
    public Matrix<double> Win { get; private set; }         // network input matrix
    public Matrix<double> Wres { get; private set; }        // network reservoir matrix
    public Matrix<double> Wout { get; private set; }        // network output matrix

    // constructor
    public Network(Matrix<double> Winput, Matrix<double> Wreservoir, Matrix<double> Woutput)
    {
        Win = Winput;
        Wres = Wreservoir;
        Wout = Woutput;
    }

    public override string ToString()
    {
        return Win.ToString();
    }
}
Lars Kristensen
  • 1,410
  • 19
  • 29
  • Indeed `Console.WriteLine(network.Wres);` for instance followed by `Console.WriteLine(network.Win);` works. So there is no need for a `ToString()` override in this case. `private set` is a good note too. – jdelange Nov 21 '15 at 12:26
0

The ToString() method you've created works on the Network class...

In other words you've made calling Network.ToString() be the stringifyed Win matrix. Naturally, you can't have three different behaviours for Network.ToString() - so what would you like it to do?

I think your question seeks to override the behaviour of network.matrix.ToString() for all Matrix fields on the network class... In this case, it's necessary to override the behaviour on the Matrix class itself, to do this, you'd need to make Win, Wres and Wout subclass of Matrix<double> with their own ToString() override as so:

public class Network
{
    public NetworkMatrix Win { get; set; }         // network input matrix
    public NetworkMatrix Wres { get; set; }        // network reservoir matrix
    public NetworkMatrix Wout { get; set; }        // network output matrix

    // constructor
    public Network(NetworkMatrix Winput, NetworkMatrix Wreservoir, NetworkMatrix Woutput)
    {
        Win = Winput;
        Wres = Wreservoir;
        Wout = Woutput;
    }

    ...
}

public class NetworkMatrix : Matrix<double>
{
    public override string ToString()
    {
        return "Overwridden tostring method.";
    }
}

Depending on how you feed the constructor, this may not be possible to send in your derived type however. Also, I haven't made the NetworkMatrix generic, but you could do NetworkMatrix<T> : Matrix<T> if you'd like.


Having said all that - I should point out that calling something like network.Win.ToString() is usually poor coding practice - other classes shouldn't know about the internals of network and you run into issues. Look up the Law of Demeter (eg https://en.wikipedia.org/wiki/Law_of_Demeter ) for more information. (In particular, it's worth asking if Win, Wres and even Wout should really be public in the first place?)

The best approach would be to use your override of the Network.ToString() method to combine the data on Win, Wres or Wout in sensible ways. Or create a matrix stringifier class which can format the strings the way you want.


Hope that's helpful. Any questions, just ask.

David E
  • 1,384
  • 9
  • 14