如何解析C#中的Octave / matlab矩阵输出?

How to parse Octave/matlab matrix output in C#?
2021-09-15
  •  译文(汉语)
  •  原文(英语)

假设我们有一个Octave / Matlab矩阵,其中填充了以字符串形式提供给我们的数据,如下所示:

N =

 Columns 1 through 6:

  0.0000e+000  0.0000e+000  0.0000e+000  0.0000e+000  0.0000e+000  0.0000e+000
  0.0000e+000  0.0000e+000  2.3423e+008  1.0809e+009  1.6893e+010  6.5398e+008

 Columns 7 through 12:

  0.0000e+000  0.0000e+000  0.0000e+000  0.0000e+000  0.0000e+000  0.0000e+000
  3.3553e+009  6.9347e+010  3.5653e+010  2.7392e+011  2.1380e+008  7.9962e+009

 Columns 13 and 14:

  9.0266e+015  2.6575e+007
  9.0265e+015  1.2970e-008

因此,每个列都有其值列表(此处每个列都2可以有更多行,我们不知道有多少行,在获得该字符串之前,我们知道列的总数)

如何list<list<double> >在运行时(从给定的字符串)将此类野兽解析为C#?

速聊1:
您可能不希望使用List <List <float >>,而是希望使用float [] [],甚至更好的是double [] [].
解决过程1

您应该首先将矩阵写入文件(在Octave / Matlab中).这些文件具有一致的格式,可让您从文件中提取数据.

而且不知道,我周围有一些代码可以将Octave矩阵解析为.NET!没关系,窗帘后面的TODO.这是更大班级的一部分,但这应该是其中的大部分.如果缺少任何关键的内容,请添加评论,然后我将其进行挖掘.

Dictionary<string, object> variables;

private bool ReadAllVariablesFromDataFile(string[] lines)
{
    int i = 0;

    while (i < lines.Length)
    {
        string line = lines[i];
        int oldI = i;
        i = ReadSingleVariable(i, lines);
    }

    return true;
}

private static bool IsDefinitionLine(string line)
{
    return (line != null && line.TrimStart().StartsWith("#"));
}

private int ReadSingleVariable(int startIndex, string[] lines)
{
    // TODO: Types other than matrix.
    OctaveVariable variable = new OctaveVariable();

    while (IsDefinitionLine(lines[startIndex]))
    {
        ProcessDefinitionLine(variable, lines[startIndex]);
        startIndex++;
    }

    if (!variable.IsInitialized)
    {
        return startIndex;
    }

    for (int i = 0; i < variable.Rows; i++)
    {
        ProcessDataLine(variable, lines[startIndex + i], i);
    }

    this.variables.Add(variable.Name, variable.Value);

    return startIndex + variable.Rows;
}

private static void ProcessDefinitionLine(OctaveVariable variable, string line)
{
    string value = GetLineValue(line);

    switch (GetLineId(line))
    {
        case "name":
            variable.Name = value;
            variable.IsInitialized = true;
            break;
        case "rows":
            variable.Rows = int.Parse(value);
            break;
        case "columns":
            variable.Columns = int.Parse(value);
            break;
        default:
            break;
    }
}

private static void ProcessDataLine(OctaveVariable variable, string line, int rowIndex)
{
    string[] values = line.Trim().Split(' ');
    double[] row = new double[variable.Columns];

    for (int i = 0; i < variable.Columns; i++)
    {
        variable.Value[rowIndex, i] = double.Parse(values[i]);
    }
}

private static string GetLineId(string line)
{
    return line.Split(':').First().TrimStart('#').Trim().ToLowerInvariant();
}

private static string GetLineValue(string line)
{
    string[] pair = line.Split(':');
    if (pair.Length < 2)
    {
        throw new ArgumentException("Invalid def line");
    }

    return pair[1].Trim();
}

Say we have an Octave/Matlab matrix filled with data given to us as string like this:

N =

 Columns 1 through 6:

  0.0000e+000  0.0000e+000  0.0000e+000  0.0000e+000  0.0000e+000  0.0000e+000
  0.0000e+000  0.0000e+000  2.3423e+008  1.0809e+009  1.6893e+010  6.5398e+008

 Columns 7 through 12:

  0.0000e+000  0.0000e+000  0.0000e+000  0.0000e+000  0.0000e+000  0.0000e+000
  3.3553e+009  6.9347e+010  3.5653e+010  2.7392e+011  2.1380e+008  7.9962e+009

 Columns 13 and 14:

  9.0266e+015  2.6575e+007
  9.0265e+015  1.2970e-008

So each Columns would have its list of values (here each Column has 2 yet it can have more rows and we do not know how many, we know totall ammount of columns before we are given that string)

How to parsae such beast into a C# list<list<double> > at runtime (from given string)?

Talk1:
You probably don't want a List<List<float>> but rather a float[][], or even better, a double[][].
Solutions1

You should start by writing the matrices to a file (in Octave/Matlab). These files have a consistent format which allows you to pull data out of them.

And wouldn'cha know it, I have some code lying around that parses Octave matrices into .NET! Never mind the TODO behind the curtain. This is part of a bigger class, but that should be most of it; if anything critical looks to be missing, add a comment and I'll dig it up.

Dictionary<string, object> variables;

private bool ReadAllVariablesFromDataFile(string[] lines)
{
    int i = 0;

    while (i < lines.Length)
    {
        string line = lines[i];
        int oldI = i;
        i = ReadSingleVariable(i, lines);
    }

    return true;
}

private static bool IsDefinitionLine(string line)
{
    return (line != null && line.TrimStart().StartsWith("#"));
}

private int ReadSingleVariable(int startIndex, string[] lines)
{
    // TODO: Types other than matrix.
    OctaveVariable variable = new OctaveVariable();

    while (IsDefinitionLine(lines[startIndex]))
    {
        ProcessDefinitionLine(variable, lines[startIndex]);
        startIndex++;
    }

    if (!variable.IsInitialized)
    {
        return startIndex;
    }

    for (int i = 0; i < variable.Rows; i++)
    {
        ProcessDataLine(variable, lines[startIndex + i], i);
    }

    this.variables.Add(variable.Name, variable.Value);

    return startIndex + variable.Rows;
}

private static void ProcessDefinitionLine(OctaveVariable variable, string line)
{
    string value = GetLineValue(line);

    switch (GetLineId(line))
    {
        case "name":
            variable.Name = value;
            variable.IsInitialized = true;
            break;
        case "rows":
            variable.Rows = int.Parse(value);
            break;
        case "columns":
            variable.Columns = int.Parse(value);
            break;
        default:
            break;
    }
}

private static void ProcessDataLine(OctaveVariable variable, string line, int rowIndex)
{
    string[] values = line.Trim().Split(' ');
    double[] row = new double[variable.Columns];

    for (int i = 0; i < variable.Columns; i++)
    {
        variable.Value[rowIndex, i] = double.Parse(values[i]);
    }
}

private static string GetLineId(string line)
{
    return line.Split(':').First().TrimStart('#').Trim().ToLowerInvariant();
}

private static string GetLineValue(string line)
{
    string[] pair = line.Split(':');
    if (pair.Length < 2)
    {
        throw new ArgumentException("Invalid def line");
    }

    return pair[1].Trim();
}
转载于:https://stackoverflow.com/questions/15560126/how-to-parse-octave-matlab-matrix-output-in-c

本人是.net程序员,因为英语不行,使用工具翻译,希望对有需要的人有所帮助
如果本文质量不好,还请谅解,毕竟这些操作还是比较费时的,英语较好的可以看原文

留言回复
我们只提供高质量资源,素材,源码,坚持 下了就能用 原则,让客户花了钱觉得值
上班时间 : 周一至周五9:00-17:30 期待您的加入