Beispiel #1
0
 /// <summary>
 /// Remove a complex assignment
 /// </summary>
 /// <param name="a"></param>
 public void Remove(ComplexAssignment a)
 {
     if (Real.Contains(a))
     {
         Real.Remove(a);
     }
     if (Imag.Contains(a))
     {
         Imag.Remove(a);
     }
     map.Remove(a.Index);
     nmap[a.Nodes].Remove(a);
 }
Beispiel #2
0
            /// <summary>
            /// Add a complex assignment
            /// </summary>
            /// <param name="a"></param>
            public void Add(ComplexAssignment a)
            {
                if (a.Real)
                {
                    Real.Add(a);
                }
                else
                {
                    Imag.Add(a);
                }

                if (!nmap.ContainsKey(a.Nodes))
                {
                    nmap.Add(a.Nodes, new HashSet <ComplexAssignment>());
                }
                nmap[a.Nodes].Add(a);
                map.Add(a.Index, a);
            }
Beispiel #3
0
        /// <summary>
        /// Match assignments
        /// </summary>
        private void MatchAssignments(AssignmentGroup group, SortedDictionary <int, ComplexAssignment> insert, SortedDictionary <int, ComplexAssignment> remove)
        {
            // Try to match all the statements in the group
            foreach (var node in group.AllNodes)
            {
                ComplexAssignment na = new ComplexAssignment();
                na.Nodes  = node;
                na.Op     = null;
                na.Index  = int.MaxValue;
                na.Length = 0;
                na.Real   = true;

                // Create the real part
                string rpart = "";
                foreach (var a in group.RealByNode(node))
                {
                    if (na.Op == null)
                    {
                        na.Op = a.Op;
                        rpart = a.Value;
                    }
                    else
                    {
                        if (a.Op == na.Op)
                        {
                            if (rpart.Length > 0)
                            {
                                rpart += " + ";
                            }
                            rpart += a.Value;
                        }
                        else
                        {
                            if (rpart.Length > 0)
                            {
                                rpart += " - ";
                            }
                            else
                            {
                                rpart += "-";
                            }
                            if (a.Value.Contains('+') || a.Value.Contains('-'))
                            {
                                rpart += "(" + a.Value + ")";
                            }
                            else
                            {
                                rpart += a.Value;
                            }
                        }
                    }

                    // Keep the first assignment to insert
                    if (a.Index < na.Index)
                    {
                        na.Index = a.Index;
                    }
                    remove.Add(a.Index, a);
                }

                // Create the imaginary part
                string ipart = "";
                foreach (var a in group.ImaginaryByNode(node))
                {
                    if (na.Op == null)
                    {
                        na.Op = a.Op;
                        ipart = a.Value;
                    }
                    else
                    {
                        if (a.Op == na.Op)
                        {
                            if (ipart.Length > 0)
                            {
                                ipart += " + ";
                            }
                            ipart += a.Value;
                        }
                        else
                        {
                            if (ipart.Length > 0)
                            {
                                ipart += " - ";
                            }
                            else
                            {
                                ipart += "-";
                            }
                            if (a.Value.Contains('+') || a.Value.Contains('-'))
                            {
                                ipart += "(" + a.Value + ")";
                            }
                            else
                            {
                                ipart += a.Value;
                            }
                        }
                    }

                    // Keep the first assignment to insert
                    if (a.Index < na.Index)
                    {
                        na.Index = a.Index;
                    }
                    remove.Add(a.Index, a);
                }

                // Build the value
                if (string.IsNullOrEmpty(ipart))
                {
                    na.Value = $"cstate.Matrix[{node.Item1}, {node.Item2}] {na.Op} {rpart};";
                }
                else
                {
                    if (string.IsNullOrEmpty(rpart))
                    {
                        rpart = "0.0";
                    }
                    na.Value = $"cstate.Matrix[{node.Item1}, {node.Item2}] {na.Op} new Complex({rpart}, {ipart});";
                }
                na.Length = na.Value.Length;
                insert.Add(na.Index, na);
            }
        }
Beispiel #4
0
        /// <summary>
        /// Group the assignments
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        private string ComplexAssignments(string code)
        {
            // Find assignments to the imaginary part and try to combine them with the real counterpart
            // The imaginary assignments are of the form: cstate.Matrix[<node1>, <node2>].Imag +=/-= <expression>;
            // We need to make sure that conditions are not broken while matching equations...

            // First clean up some annoying brackets
            code = Regex.Replace(code, @"\((?<inner>cstate.Matrix\[\w+, \w+\][^;]+)\);", (Match m) => m.Groups["inner"].Value + ";");

            SortedDictionary <int, ComplexAssignment> remove = new SortedDictionary <int, ComplexAssignment>();
            SortedDictionary <int, ComplexAssignment> insert = new SortedDictionary <int, ComplexAssignment>();

            // Find all the statements and their starting positions
            assignments.Clear();
            MatchCollection ms = Regex.Matches(code, @"cstate\.Matrix\[(?<n1>\w+), (?<n2>\w+)\](?<imag>\.Imag)? (?<op>[\+\-]\=) (?<value>[^;]+);");

            foreach (Match m in ms)
            {
                ComplexAssignment a = new ComplexAssignment();
                a.Nodes = new Tuple <string, string>(m.Groups["n1"].Value, m.Groups["n2"].Value);
                a.Op    = m.Groups["op"].Value;
                a.Value = m.Groups["value"].Value;
                if (m.Groups["imag"].Success)
                {
                    a.Real = false;
                }
                else
                {
                    a.Real = true;
                }
                a.Index  = m.Index;
                a.Length = m.Length;
                assignments.Add(a);
            }

            // Now match them while keeping track of if-statements, comments and strings
            Stack <AssignmentGroup> currentgroup = new Stack <AssignmentGroup>();

            currentgroup.Push(new AssignmentGroup());
            Code.LevelExecute(code,
                              (int i, int lvl) => currentgroup.Push(new AssignmentGroup()),
                              (int i, int lvl) => MatchAssignments(currentgroup.Pop(), insert, remove),
                              (int i, int lvl) => {
                if (assignments.Contains(i))
                {
                    currentgroup.Peek().Add(assignments[i]);
                }
            });
            MatchAssignments(currentgroup.Pop(), insert, remove);

            // Remove the old statement assignments and add the new ones
            int  offset = 0;
            var  it_insert = insert.GetEnumerator();
            var  it_remove = remove.GetEnumerator();
            bool ic = it_insert.MoveNext(), rc = it_remove.MoveNext();

            while (ic || rc)
            {
                if (ic && rc)
                {
                    // First try to add
                    if (it_insert.Current.Key <= it_remove.Current.Key)
                    {
                        int start = it_insert.Current.Key + offset;
                        code    = code.Substring(0, start) + it_insert.Current.Value.Value + code.Substring(start);
                        offset += it_insert.Current.Value.Length;
                        ic      = it_insert.MoveNext();
                    }
                    else
                    {
                        // Only now remove
                        int start = it_remove.Current.Key + offset;
                        code    = code.Substring(0, start) + code.Substring(start + it_remove.Current.Value.Length);
                        offset -= it_remove.Current.Value.Length;
                        rc      = it_remove.MoveNext();
                    }
                }
                else if (ic)
                {
                    int start = it_insert.Current.Key + offset;
                    code    = code.Substring(0, start) + it_insert.Current.Value.Value + code.Substring(start);
                    offset += it_insert.Current.Value.Length;
                    ic      = it_insert.MoveNext();
                }
                else if (rc)
                {
                    // Only now remove
                    int start = it_remove.Current.Key + offset;
                    code    = code.Substring(0, start) + code.Substring(start + it_remove.Current.Value.Length);
                    offset -= it_remove.Current.Value.Length;
                    rc      = it_remove.MoveNext();
                }
            }

            return(code);
        }