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;
3using System.Threading.Tasks;
10
12{
17 {
27 : base(Left, Right, Start, Length, Expression)
28 {
29 }
30
37 {
38 IElement Left = this.left.Evaluate(Variables);
39 IElement Right = this.right.Evaluate(Variables);
40
41 return EvaluatePower(Left, Right, this);
42 }
43
49 public override async Task<IElement> EvaluateAsync(Variables Variables)
50 {
51 if (!this.isAsync)
52 return this.Evaluate(Variables);
53
54 IElement Left = await this.left.EvaluateAsync(Variables);
55 IElement Right = await this.right.EvaluateAsync(Variables);
56
57 return EvaluatePower(Left, Right, this);
58 }
59
67 public static IElement EvaluatePower(IElement Left, IElement Right, ScriptNode Node)
68 {
69 if (Right.AssociatedObjectValue is double DR)
70 {
71 if (Left.AssociatedObjectValue is double DL)
72 return new DoubleNumber(Math.Pow(DL, DR));
73
74 if (Left is IRingElement LE)
75 {
76 if (DR >= long.MinValue && DR <= long.MaxValue && Math.Truncate(DR) == DR)
77 {
78 long n = (long)DR;
79
80 if (n < 0)
81 {
82 LE = LE.Invert();
83 if (LE is null)
84 throw new ScriptRuntimeException("Base element not invertible.", Node);
85
86 n = -n;
87 }
88 else if (n == 0)
89 {
91 throw new ScriptRuntimeException("Base element ring does not have unity.", Node);
92
93 return LE2.One;
94 }
95
96 IRingElement Result = null;
97
98 while (n > 0)
99 {
100 if ((n & 1) == 1)
101 {
102 if (Result is null)
103 Result = LE;
104 else
105 Result = (IRingElement)Multiply.EvaluateMultiplication(Result, LE, Node);
106 }
107
108 n >>= 1;
109 if (n > 0)
110 LE = (IRingElement)Multiply.EvaluateMultiplication(LE, LE, Node);
111 }
112
113 return Result;
114 }
115 else
116 throw new ScriptRuntimeException("Exponent too large.", Node);
117 }
118 }
119
120 if (Left.IsScalar)
121 {
122 if (Right.IsScalar)
123 throw new ScriptRuntimeException("Power operation could not be computed.", Node);
124 else
125 {
127
128 foreach (IElement RightChild in Right.ChildElements)
129 Elements.Add(EvaluatePower(Left, RightChild, Node));
130
131 return Right.Encapsulate(Elements, Node);
132 }
133 }
134 else
135 {
136 if (Right.IsScalar)
137 {
139
140 foreach (IElement LeftChild in Left.ChildElements)
141 Elements.Add(EvaluatePower(LeftChild, Right, Node));
142
143 return Left.Encapsulate(Elements, Node);
144 }
145 else
146 {
147 ICollection<IElement> LeftChildren = Left.ChildElements;
148 ICollection<IElement> RightChildren = Right.ChildElements;
149
150 if (LeftChildren.Count == RightChildren.Count)
151 {
153 IEnumerator<IElement> eLeft = LeftChildren.GetEnumerator();
154 IEnumerator<IElement> eRight = RightChildren.GetEnumerator();
155
156 try
157 {
158 while (eLeft.MoveNext() && eRight.MoveNext())
159 Elements.Add(EvaluatePower(eLeft.Current, eRight.Current, Node));
160 }
161 finally
162 {
163 eLeft.Dispose();
164 eRight.Dispose();
165 }
166
167 return Left.Encapsulate(Elements, Node);
168 }
169 else
170 {
172
173 foreach (IElement LeftChild in LeftChildren)
174 {
176
177 foreach (IElement RightChild in RightChildren)
178 RightResult.Add(EvaluatePower(LeftChild, RightChild, Node));
179
180 LeftResult.Add(Right.Encapsulate(RightResult, Node));
181 }
182
183 return Left.Encapsulate(LeftResult, Node);
184 }
185 }
186 }
187 }
188
195 public ScriptNode Differentiate(string VariableName, Variables Variables)
196 {
197 int Start = this.Start;
198 int Len = this.Length;
200
201 if (this.left is ConstantElement ConstantBase)
202 {
203 return this.DifferentiationChainRule(VariableName, Variables, this.right,
204 new Multiply(
205 this,
206 new Ln(ConstantBase, Start, Len, Expression),
207 Start, Len, Expression));
208 }
209 else if (this.left is IDifferentiable Left)
210 {
211 if (this.right is ConstantElement ConstantExp)
212 {
213 if (ConstantExp.Constant.Equals(DoubleNumber.OneElement))
214 return Left.Differentiate(VariableName, Variables);
215 else if (ConstantExp.Constant.Equals(DoubleNumber.TwoElement))
216 {
217 return this.DifferentiationChainRule(VariableName, Variables, this.left,
218 new Multiply(
219 ConstantExp,
220 this.left,
221 Start, Len, Expression));
222 }
223 else
224 {
225 return this.DifferentiationChainRule(VariableName, Variables, this.left,
226 new Multiply(
227 ConstantExp,
228 new Power(
229 this.left,
230 new ConstantElement(Subtract.EvaluateSubtraction(ConstantExp.Constant, DoubleNumber.OneElement, this), Start, Len, Expression),
231 Start, Len, Expression),
232 Start, Len, Expression));
233 }
234 }
235 else if (this.right is IDifferentiable Right)
236 {
237 return new Multiply(
238 this,
239 new Add(
240 new Multiply(
241 Left.Differentiate(VariableName, Variables),
242 new Divide(this.right, this.left, Start, Len, Expression),
243 Start, Len, Expression),
244 new Multiply(
245 Right.Differentiate(VariableName, Variables),
246 new Ln(this.left, Start, Len, Expression),
247 Start, Len, Expression),
248 Start, Len, Expression),
249 Start, Len, Expression);
250 }
251 else
252 throw new ScriptRuntimeException("Operands not differentiable.", this);
253 }
254 else
255 throw new ScriptRuntimeException("Operands not differentiable.", this);
256 }
257
258 }
259}
A chunked list is a linked list of chunks of objects of type T .
Definition: ChunkedList.cs:54
void Add(T Item)
Adds an item to the collection.
Definition: ChunkedList.cs:272
Class managing a script expression.
Definition: Expression.cs:41
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:49
Power(ScriptNode Left, ScriptNode Right, int Start, int Length, Expression Expression)
Power operator.
Definition: Power.cs:26
override IElement Evaluate(Variables Variables)
Evaluates the node, using the variables provided in the Variables collection.
Definition: Power.cs:36
ScriptNode Differentiate(string VariableName, Variables Variables)
Differentiates a script node, if possible.
Definition: Power.cs:195
static IElement EvaluatePower(IElement Left, IElement Right, ScriptNode Node)
Calculates Left ^ Right.
Definition: Power.cs:67
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:21
object AssociatedObjectValue
Associated object value.
Definition: IElement.cs:34
ICollection< IElement > ChildElements
An enumeration of child elements. If the element is a scalar, this property will return null.
Definition: IElement.cs:50
IElement Encapsulate(ChunkedList< 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:42
Basic interface for all types of ring elements.
Definition: IRingElement.cs:10
Base interface for lambda expressions.