Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
BooleanMatrix.cs
1using System.Collections.Generic;
2using System.Text;
9
11{
15 public sealed class BooleanMatrix : RingElement, IMatrix
16 {
17 private bool[,] values;
18 private IElement[,] matrixElements;
19 private ICollection<IElement> elements;
20 private readonly int rows;
21 private readonly int columns;
22
27 public BooleanMatrix(bool[,] Values)
28 {
29 this.values = Values;
30 this.elements = null;
31 this.matrixElements = null;
32 this.rows = Values.GetLength(0);
33 this.columns = Values.GetLength(1);
34 }
35
42 public BooleanMatrix(int Rows, int Columns, ICollection<IElement> Elements)
43 {
44 this.values = null;
45 this.elements = Elements;
46 this.matrixElements = null;
47 this.rows = Rows;
48 this.columns = Columns;
49 }
50
54 public bool[,] Values
55 {
56 get
57 {
58 if (this.values is null)
59 {
60 bool[,] v = new bool[this.rows, this.columns];
61 int x = 0;
62 int y = 0;
63
64 foreach (IElement Element in this.elements)
65 {
66 if (!(Element.AssociatedObjectValue is bool b))
67 b = false;
68
69 v[y, x++] = b;
70 if (x >= this.columns)
71 {
72 y++;
73 x = 0;
74 }
75 }
76
77 this.values = v;
78 }
79
80 return this.values;
81 }
82 }
83
87 public ICollection<IElement> Elements
88 {
89 get
90 {
91 if (this.elements is null)
92 {
93 int x, y, i = 0;
94 IElement[] v = new IElement[this.rows * this.columns];
95
96 for (y = 0; y < this.rows; y++)
97 {
98 for (x = 0; x < this.columns; x++)
99 v[i++] = new BooleanValue(this.values[y, x]);
100 }
101
102 this.elements = v;
103 }
104
105 return this.elements;
106 }
107 }
108
113 {
114 get
115 {
116 if (this.matrixElements is null)
117 {
118 IElement[,] v = new IElement[this.rows, this.columns];
119 int x = 0;
120 int y = 0;
121
122 foreach (IElement E in this.Elements)
123 {
124 v[y, x++] = E;
125 if (x >= this.columns)
126 {
127 y++;
128 x = 0;
129 }
130 }
131
132 this.matrixElements = v;
133 }
134
135 return this.matrixElements;
136 }
137 }
138
142 public int Rows => this.rows;
143
147 public int Columns => this.columns;
148
150 public override string ToString()
151 {
152 bool[,] v = this.Values;
153 StringBuilder sb = null;
154 bool First;
155 int x, y;
156
157 for (y = 0; y < this.rows; y++)
158 {
159 if (sb is null)
160 sb = new StringBuilder("[[");
161 else
162 sb.Append(",\r\n [");
163
164 First = true;
165 for (x = 0; x < this.columns; x++)
166 {
167 if (First)
168 First = false;
169 else
170 sb.Append(", ");
171
172 sb.Append(Expression.ToString(v[y, x]));
173 }
174
175 sb.Append(']');
176 }
177
178 if (sb is null)
179 sb = new StringBuilder("[[]]");
180 else
181 sb.Append(']');
182
183 return sb.ToString();
184 }
185
189 public override IRing AssociatedRing
190 {
191 get
192 {
193 if (this.associatedMatrixSpace is null)
194 this.associatedMatrixSpace = new BooleanMatrices(this.rows, this.columns);
195
196 return this.associatedMatrixSpace;
197 }
198 }
199
200 private BooleanMatrices associatedMatrixSpace = null;
201
205 public override object AssociatedObjectValue => this;
206
213 {
214 return this.ToDoubleMatrix().MultiplyLeft(Element);
215 }
216
223 {
224 return this.ToDoubleMatrix().MultiplyRight(Element);
225 }
226
231 public override IRingElement Invert()
232 {
233 if (this.rows != this.columns)
234 return null;
235
236 return this.ToDoubleMatrix().Invert();
237 }
238
250 public IMatrix Reduce(bool Eliminate, bool BreakIfZero, out int Rank, out ICommutativeRingWithIdentityElement Factor)
251 {
252 return this.ToDoubleMatrix().Reduce(Eliminate, BreakIfZero, out Rank, out Factor);
253 }
254
260 {
261 bool[,] Values = this.Values;
262 double[,] v = new double[this.rows, this.columns];
263 int x, y;
264
265 for (y = 0; y < this.rows; y++)
266 {
267 for (x = 0; x < this.columns; x++)
268 v[y, x] = Values[y, x] ? 1 : 0;
269 }
270
271 return new DoubleMatrix(v);
272 }
273
280 {
281 return this.ToDoubleMatrix().Add(Element);
282 }
283
288 public override IGroupElement Negate()
289 {
290 return this;
291 }
292
298 public override bool Equals(object obj)
299 {
300 if (!(obj is BooleanMatrix Matrix))
301 return false;
302
303 if (this.columns != Matrix.columns || this.rows != Matrix.rows)
304 return false;
305
306 bool[,] V1 = this.Values;
307 bool[,] V2 = Matrix.Values;
308 int x, y;
309
310 for (y = 0; y < this.rows; y++)
311 {
312 for (x = 0; x < this.columns; x++)
313 {
314 if (V1[y, x] != V2[y, x])
315 return false;
316 }
317 }
318
319 return true;
320 }
321
326 public override int GetHashCode()
327 {
328 int Result = 0;
329 int x, y;
330 int i = 0;
331
332 for (y = 0; y < this.rows; y++)
333 {
334 for (x = 0; x < this.columns; x++)
335 {
336 if (this.values[y, x])
337 Result ^= (1 << i);
338
339 i++;
340 i &= 31;
341 }
342 }
343
344 return Result;
345 }
346
350 public override bool IsScalar => false;
351
355 public override ICollection<IElement> ChildElements => this.Elements;
356
363 public override IElement Encapsulate(ICollection<IElement> Elements, ScriptNode Node)
364 {
365 return MatrixDefinition.Encapsulate(Elements, this.rows, this.columns, Node);
366 }
367
372 {
373 get
374 {
375 if (this.zero is null)
376 this.zero = new BooleanMatrix(new bool[this.rows, this.columns]);
377
378 return this.zero;
379 }
380 }
381
382 private BooleanMatrix zero = null;
383
387 public int Dimension => this.rows;
388
392 public ICollection<IElement> VectorElements
393 {
394 get
395 {
396 if (!(this.rowVectors is null))
397 return this.rowVectors;
398
399 bool[,] v = this.Values;
400 LinkedList<IElement> Rows = new LinkedList<IElement>();
401 int x, y;
402 bool[] r;
403
404 for (y = 0; y < this.rows; y++)
405 {
406 r = new bool[this.columns];
407
408 for (x = 0; x < this.columns; x++)
409 r[x] = v[y, x];
410
411 Rows.AddLast(new BooleanVector(r));
412 }
413
414 this.rowVectors = Rows;
415 return Rows;
416 }
417 }
418
419 private LinkedList<IElement> rowVectors = null;
420
426 {
427 bool[,] v = new bool[this.columns, this.rows];
428 bool[,] Values = this.Values;
429 int x, y;
430
431 for (y = 0; y < this.rows; y++)
432 {
433 for (x = 0; x < this.columns; x++)
434 v[x, y] = Values[y, x];
435 }
436
437 return new BooleanMatrix(v);
438 }
439
445 {
446 return this.Transpose();
447 }
448
454 public IElement GetElement(int Index)
455 {
456 if (Index < 0 || Index >= this.rows)
457 throw new ScriptException("Index out of bounds.");
458
459 bool[,] M = this.Values;
460 bool[] V = new bool[this.columns];
461 int i;
462
463 for (i = 0; i < this.columns; i++)
464 V[i] = M[Index, i];
465
466 return new BooleanVector(V);
467 }
468
474 public void SetElement(int Index, IElement Value)
475 {
476 if (Index < 0 || Index >= this.rows)
477 throw new ScriptException("Index out of bounds.");
478
479 if (!(Value is BooleanVector V))
480 throw new ScriptException("Row vectors in a boolean matrix are required to be boolean vectors.");
481
482 if (V.Dimension != this.columns)
483 throw new ScriptException("Dimension mismatch.");
484
485 bool[] V2 = V.Values;
486 bool[,] M = this.Values;
487 this.elements = null;
488
489 int i;
490
491 for (i = 0; i < this.columns; i++)
492 M[Index, i] = V2[i];
493 }
494
501 public IElement GetElement(int Column, int Row)
502 {
503 if (Column < 0 || Column >= this.columns || Row < 0 || Row >= this.rows)
504 throw new ScriptException("Index out of bounds.");
505
506 return new BooleanValue(this.Values[Row, Column]);
507 }
508
515 public void SetElement(int Column, int Row, IElement Value)
516 {
517 if (Column < 0 || Column >= this.columns || Row < 0 || Row >= this.rows)
518 throw new ScriptException("Index out of bounds.");
519
520 if (!(Value.AssociatedObjectValue is bool V))
521 throw new ScriptException("Elements in a boolean matrix must be boolean values.");
522
523 bool[,] M = this.Values;
524 this.elements = null;
525
526 M[Row, Column] = V;
527 }
528
534 public IVector GetRow(int Row)
535 {
536 if (Row < 0 || Row >= this.rows)
537 throw new ScriptException("Index out of bounds.");
538
539 bool[,] M = this.Values;
540 bool[] V = new bool[this.columns];
541 int i;
542
543 for (i = 0; i < this.columns; i++)
544 V[i] = M[Row, i];
545
546 return new BooleanVector(V);
547 }
548
554 public IVector GetColumn(int Column)
555 {
556 if (Column < 0 || Column >= this.columns)
557 throw new ScriptException("Index out of bounds.");
558
559 bool[,] M = this.Values;
560 bool[] V = new bool[this.rows];
561 int i;
562
563 for (i = 0; i < this.rows; i++)
564 V[i] = M[i, Column];
565
566 return new BooleanVector(V);
567 }
568
574 public void SetRow(int Row, IVector Vector)
575 {
576 if (Row < 0 || Row >= this.rows)
577 throw new ScriptException("Index out of bounds.");
578
579 if (Vector.Dimension != this.columns)
580 throw new ScriptException("Vector dimension does not match number of columns");
581
582 if (!(Vector is BooleanVector V))
583 throw new ScriptException("Row vectors in a boolean matrix must be boolean vectors.");
584
585 bool[] V2 = V.Values;
586 bool[,] M = this.Values;
587 this.elements = null;
588 int i;
589
590 for (i = 0; i < this.columns; i++)
591 M[Row, i] = V2[i];
592 }
593
599 public void SetColumn(int Column, IVector Vector)
600 {
601 if (Column < 0 || Column >= this.columns)
602 throw new ScriptException("Index out of bounds.");
603
604 if (Vector.Dimension != this.rows)
605 throw new ScriptException("Vector dimension does not match number of rows");
606
607 if (!(Vector is BooleanVector V))
608 throw new ScriptException("Column vectors in a boolean matrix must be boolean vectors.");
609
610 bool[] V2 = V.Values;
611 bool[,] M = this.Values;
612 this.elements = null;
613 int i;
614
615 for (i = 0; i < this.rows; i++)
616 M[i, Column] = V2[i];
617 }
618
619 }
620}
Base class for all types of elements.
Definition: Element.cs:13
abstract object AssociatedObjectValue
Associated object value.
Definition: Element.cs:46
Base class for all types of ring elements.
Definition: RingElement.cs:10
Base class for script exceptions.
Class managing a script expression.
Definition: Expression.cs:39
static string ToString(double Value)
Converts a value to a string, that can be parsed as part of an expression.
Definition: Expression.cs:4496
Base class for all nodes in a parsed script tree.
Definition: ScriptNode.cs:69
Boolean-valued number.
Definition: BooleanValue.cs:12
Pseudo-ring of Boolean-valued matrices.
IVector GetColumn(int Column)
Gets a column vector from the matrix.
void SetRow(int Row, IVector Vector)
Gets a row vector from the matrix.
override IRingElement Invert()
Inverts the element, if possible.
IMatrix ConjugateTranspose()
Returns a conjugate transposed matrix.
int Dimension
Dimension of matrix, if seen as a vector of row vectors.
override IRingElement MultiplyLeft(IRingElement Element)
Tries to multiply an element to the current element, from the left.
override IElement Encapsulate(ICollection< IElement > Elements, ScriptNode Node)
Encapsulates a set of elements into a similar structure as that provided by the current element.
void SetElement(int Column, int Row, IElement Value)
Sets an element in the matrix.
override IAbelianGroupElement Zero
Returns the zero element of the group.
ICollection< IElement > VectorElements
Vector of row vectors.
IElement[,] MatrixElements
Matrix elements
override int GetHashCode()
Calculates a hash code of the element.
IElement GetElement(int Index)
Gets an element of the vector.
override object AssociatedObjectValue
Associated object value.
override bool Equals(object obj)
Compares the element to another.
void SetElement(int Index, IElement Value)
Sets an element in the vector.
BooleanMatrix(bool[,] Values)
Boolean-valued matrix.
IMatrix Reduce(bool Eliminate, bool BreakIfZero, out int Rank, out ICommutativeRingWithIdentityElement Factor)
Reduces a matrix.
void SetColumn(int Column, IVector Vector)
Gets a column vector from the matrix.
ICollection< IElement > Elements
Matrix elements.
override ICollection< IElement > ChildElements
An enumeration of child elements. If the element is a scalar, this property will return null.
DoubleMatrix ToDoubleMatrix()
Converts matrix to a double-valued matrix.
bool[,] Values
Matrix element values.
override IAbelianGroupElement Add(IAbelianGroupElement Element)
Tries to add an element to the current element.
override bool IsScalar
If the element represents a scalar value.
IVector GetRow(int Row)
Gets a row vector from the matrix.
override IGroupElement Negate()
Negates the element.
override IRing AssociatedRing
Associated Ring.
BooleanMatrix(int Rows, int Columns, ICollection< IElement > Elements)
Boolean-valued vector.
IElement GetElement(int Column, int Row)
Gets an element of the matrix.
IMatrix Transpose()
Returns a transposed matrix.
override IRingElement MultiplyRight(IRingElement Element)
Tries to multiply an element to the current element, from the right.
IMatrix Reduce(bool Eliminate, bool BreakIfZero, out int Rank, out ICommutativeRingWithIdentityElement Factor)
Reduces a matrix.
override IRingElement MultiplyLeft(IRingElement Element)
Tries to multiply an element to the current element, from the left.
override IRingElement MultiplyRight(IRingElement Element)
Tries to multiply an element to the current element, from the right.
override IRingElement Invert()
Inverts the element, if possible.
override IAbelianGroupElement Add(IAbelianGroupElement Element)
Tries to add an element to the current element.
static IMatrix Encapsulate(ICollection< IElement > Rows, ScriptNode Node)
Encapsulates the elements of a matrix.
Basic interface for all types of abelian group elements.
Basic interface for all types of commutative ring with identity elements.
Basic interface for all types of elements.
Definition: IElement.cs:20
object AssociatedObjectValue
Associated object value.
Definition: IElement.cs:33
Basic interface for all types of group elements.
Definition: IGroupElement.cs:9
Basic interface for matrices.
Definition: IMatrix.cs:9
Basic interface for all types of ring elements.
Definition: IRingElement.cs:10
Basic interface for vectors.
Definition: IVector.cs:9
int Dimension
Dimension of vector.
Definition: IVector.cs:14
Basic interface for all types of rings.
Definition: IRing.cs:10