Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
Power.cs
1using System;
2using System.Collections.Generic;
3using System.Threading.Tasks;
9
11{
16 {
26 : base(Left, Right, Start, Length, Expression)
27 {
28 }
29
36 {
37 IElement Left = this.left.Evaluate(Variables);
38 IElement Right = this.right.Evaluate(Variables);
39
40 return EvaluatePower(Left, Right, this);
41 }
42
48 public override async Task<IElement> EvaluateAsync(Variables Variables)
49 {
50 if (!this.isAsync)
51 return this.Evaluate(Variables);
52
53 IElement Left = await this.left.EvaluateAsync(Variables);
54 IElement Right = await this.right.EvaluateAsync(Variables);
55
56 return EvaluatePower(Left, Right, this);
57 }
58
66 public static IElement EvaluatePower(IElement Left, IElement Right, ScriptNode Node)
67 {
68 if (Right.AssociatedObjectValue is double DR)
69 {
70 if (Left.AssociatedObjectValue is double DL)
71 return new DoubleNumber(Math.Pow(DL, DR));
72
73 if (Left is IRingElement LE)
74 {
75 if (DR >= long.MinValue && DR <= long.MaxValue && Math.Truncate(DR) == DR)
76 {
77 long n = (long)DR;
78
79 if (n < 0)
80 {
81 LE = LE.Invert();
82 if (LE is null)
83 throw new ScriptRuntimeException("Base element not invertible.", Node);
84
85 n = -n;
86 }
87 else if (n == 0)
88 {
90 throw new ScriptRuntimeException("Base element ring does not have unity.", Node);
91
92 return LE2.One;
93 }
94
95 IRingElement Result = null;
96
97 while (n > 0)
98 {
99 if ((n & 1) == 1)
100 {
101 if (Result is null)
102 Result = LE;
103 else
104 Result = (IRingElement)Multiply.EvaluateMultiplication(Result, LE, Node);
105 }
106
107 n >>= 1;
108 if (n > 0)
109 LE = (IRingElement)Multiply.EvaluateMultiplication(LE, LE, Node);
110 }
111
112 return Result;
113 }
114 else
115 throw new ScriptRuntimeException("Exponent too large.", Node);
116 }
117 }
118
119 if (Left.IsScalar)
120 {
121 if (Right.IsScalar)
122 throw new ScriptRuntimeException("Power operation could not be computed.", Node);
123 else
124 {
125 LinkedList<IElement> Elements = new LinkedList<IElement>();
126
127 foreach (IElement RightChild in Right.ChildElements)
128 Elements.AddLast(EvaluatePower(Left, RightChild, Node));
129
130 return Right.Encapsulate(Elements, Node);
131 }
132 }
133 else
134 {
135 if (Right.IsScalar)
136 {
137 LinkedList<IElement> Elements = new LinkedList<IElement>();
138
139 foreach (IElement LeftChild in Left.ChildElements)
140 Elements.AddLast(EvaluatePower(LeftChild, Right, Node));
141
142 return Left.Encapsulate(Elements, Node);
143 }
144 else
145 {
146 ICollection<IElement> LeftChildren = Left.ChildElements;
147 ICollection<IElement> RightChildren = Right.ChildElements;
148
149 if (LeftChildren.Count == RightChildren.Count)
150 {
151 LinkedList<IElement> Elements = new LinkedList<IElement>();
152 IEnumerator<IElement> eLeft = LeftChildren.GetEnumerator();
153 IEnumerator<IElement> eRight = RightChildren.GetEnumerator();
154
155 try
156 {
157 while (eLeft.MoveNext() && eRight.MoveNext())
158 Elements.AddLast(EvaluatePower(eLeft.Current, eRight.Current, Node));
159 }
160 finally
161 {
162 eLeft.Dispose();
163 eRight.Dispose();
164 }
165
166 return Left.Encapsulate(Elements, Node);
167 }
168 else
169 {
170 LinkedList<IElement> LeftResult = new LinkedList<IElement>();
171
172 foreach (IElement LeftChild in LeftChildren)
173 {
174 LinkedList<IElement> RightResult = new LinkedList<IElement>();
175
176 foreach (IElement RightChild in RightChildren)
177 RightResult.AddLast(EvaluatePower(LeftChild, RightChild, Node));
178
179 LeftResult.AddLast(Right.Encapsulate(RightResult, Node));
180 }
181
182 return Left.Encapsulate(LeftResult, Node);
183 }
184 }
185 }
186 }
187
194 public ScriptNode Differentiate(string VariableName, Variables Variables)
195 {
196 int Start = this.Start;
197 int Len = this.Length;
199
200 if (this.left is ConstantElement ConstantBase)
201 {
202 return this.DifferentiationChainRule(VariableName, Variables, this.right,
203 new Multiply(
204 this,
205 new Ln(ConstantBase, Start, Len, Expression),
206 Start, Len, Expression));
207 }
208 else if (this.left is IDifferentiable Left)
209 {
210 if (this.right is ConstantElement ConstantExp)
211 {
212 if (ConstantExp.Constant.Equals(DoubleNumber.OneElement))
213 return Left.Differentiate(VariableName, Variables);
214 else if (ConstantExp.Constant.Equals(DoubleNumber.TwoElement))
215 {
216 return this.DifferentiationChainRule(VariableName, Variables, this.left,
217 new Multiply(
218 ConstantExp,
219 this.left,
220 Start, Len, Expression));
221 }
222 else
223 {
224 return this.DifferentiationChainRule(VariableName, Variables, this.left,
225 new Multiply(
226 ConstantExp,
227 new Power(
228 this.left,
229 new ConstantElement(Subtract.EvaluateSubtraction(ConstantExp.Constant, DoubleNumber.OneElement, this), Start, Len, Expression),
230 Start, Len, Expression),
231 Start, Len, Expression));
232 }
233 }
234 else if (this.right is IDifferentiable Right)
235 {
236 return new Multiply(
237 this,
238 new Add(
239 new Multiply(
240 Left.Differentiate(VariableName, Variables),
241 new Divide(this.right, this.left, Start, Len, Expression),
242 Start, Len, Expression),
243 new Multiply(
244 Right.Differentiate(VariableName, Variables),
245 new Ln(this.left, Start, Len, Expression),
246 Start, Len, Expression),
247 Start, Len, Expression),
248 Start, Len, Expression);
249 }
250 else
251 throw new ScriptRuntimeException("Operands not differentiable.", this);
252 }
253 else
254 throw new ScriptRuntimeException("Operands not differentiable.", this);
255 }
256
257 }
258}
Class managing a script expression.
Definition: Expression.cs:39
Base class for all binary operators.
ScriptNode right
Right operand.
ScriptNode left
Left operand.
bool isAsync
If subtree is asynchroneous.
Represents a constant element value.
Base class for all nodes in a parsed script tree.
Definition: ScriptNode.cs:69
int Length
Length of expression covered by node.
Definition: ScriptNode.cs:101
ScriptNode DifferentiationChainRule(string VariableName, Variables Variables, ScriptNode Argument, ScriptNode Differentiation)
Implements the differentiation chain rule, by differentiating the argument and multiplying it to the ...
Definition: ScriptNode.cs:195
Expression Expression
Expression of which the node is a part.
Definition: ScriptNode.cs:177
int Start
Start position in script expression.
Definition: ScriptNode.cs:92
abstract IElement Evaluate(Variables Variables)
Evaluates the node, using the variables provided in the Variables collection. This method should be ...
virtual Task< IElement > EvaluateAsync(Variables Variables)
Evaluates the node, using the variables provided in the Variables collection. This method should be ...
Definition: ScriptNode.cs:158
static readonly DoubleNumber OneElement
1
Definition: DoubleNumber.cs:21
static readonly DoubleNumber TwoElement
2
Definition: DoubleNumber.cs:26
static IElement EvaluateMultiplication(IElement Left, IElement Right, ScriptNode Node)
Multiplies two operands.
Definition: Multiply.cs:69
override async Task< IElement > EvaluateAsync(Variables Variables)
Evaluates the node, using the variables provided in the Variables collection.
Definition: Power.cs:48
Power(ScriptNode Left, ScriptNode Right, int Start, int Length, Expression Expression)
Power operator.
Definition: Power.cs:25
override IElement Evaluate(Variables Variables)
Evaluates the node, using the variables provided in the Variables collection.
Definition: Power.cs:35
ScriptNode Differentiate(string VariableName, Variables Variables)
Differentiates a script node, if possible.
Definition: Power.cs:194
static IElement EvaluatePower(IElement Left, IElement Right, ScriptNode Node)
Calculates Left ^ Right.
Definition: Power.cs:66
static IElement EvaluateSubtraction(IElement Left, IElement Right, ScriptNode Node)
Subtracts the right operand from the left one.
Definition: Subtract.cs:65
Collection of variables.
Definition: Variables.cs:25
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
ICollection< IElement > ChildElements
An enumeration of child elements. If the element is a scalar, this property will return null.
Definition: IElement.cs:49
IElement Encapsulate(ICollection< IElement > Elements, ScriptNode Node)
Encapsulates a set of elements into a similar structure as that provided by the current element.
bool IsScalar
If the element represents a scalar value.
Definition: IElement.cs:41
Basic interface for all types of ring elements.
Definition: IRingElement.cs:10
Base interface for lambda expressions.