-
-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
#662 - The simplification of trigonometric and inverse trigonometric …
…functions is not correct.
- Loading branch information
Showing
12 changed files
with
423 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
// Copyright (c) Dmytro Kyshchenko. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
||
namespace xFunc.Maths.Expressions.Domains; | ||
|
||
/// <summary> | ||
/// Represents a domain of function. | ||
/// </summary> | ||
public readonly struct Domain : IEquatable<Domain> | ||
{ | ||
private readonly DomainRange[] ranges; | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="Domain"/> struct. | ||
/// </summary> | ||
/// <param name="ranges">The array of ranges.</param> | ||
public Domain(DomainRange[] ranges) | ||
=> this.ranges = ranges; // TODO: validate? | ||
|
||
/// <summary> | ||
/// Indicates whether <paramref name="left"/> domain is equal to the <paramref name="right"/> domain. | ||
/// </summary> | ||
/// <param name="left">The left domain.</param> | ||
/// <param name="right">The right domain.</param> | ||
/// <returns><c>true</c> if the <paramref name="left"/> domain is equal to the <paramref name="right"/> domain; otherwise, <c>false</c>.</returns> | ||
public static bool operator ==(Domain left, Domain right) | ||
=> left.Equals(right); | ||
|
||
/// <summary> | ||
/// Indicates whether <paramref name="left"/> domain is not equal to the <paramref name="right"/> domain. | ||
/// </summary> | ||
/// <param name="left">The left domain.</param> | ||
/// <param name="right">The right domain.</param> | ||
/// <returns><c>true</c> if the <paramref name="left"/> domain is not equal to the <paramref name="right"/> domain; otherwise, <c>false</c>.</returns> | ||
public static bool operator !=(Domain left, Domain right) | ||
=> !left.Equals(right); | ||
|
||
/// <inheritdoc /> | ||
public bool Equals(Domain other) | ||
=> ranges.Equals(other.ranges); | ||
|
||
/// <inheritdoc /> | ||
public override bool Equals(object? obj) | ||
=> obj is Domain other && Equals(other); | ||
|
||
/// <inheritdoc /> | ||
public override int GetHashCode() | ||
=> ranges.GetHashCode(); | ||
|
||
/// <inheritdoc /> | ||
public override string ToString() | ||
=> string.Join(", ", ranges); | ||
|
||
/// <summary> | ||
/// Determines whether the <paramref name="value"/> number is in the domain of the function. | ||
/// </summary> | ||
/// <param name="value">The number.</param> | ||
/// <returns><c>true</c>, if the <paramref name="value"/> number is in the domain, otherwise, <c>false</c>.</returns> | ||
public bool IsInRange(NumberValue value) | ||
{ | ||
foreach (var range in ranges) | ||
if (range.IsInRange(value)) | ||
return true; | ||
|
||
return false; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
// Copyright (c) Dmytro Kyshchenko. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
||
namespace xFunc.Maths.Expressions.Domains; | ||
|
||
/// <summary> | ||
/// The builder for <see cref="DomainRange"/>. | ||
/// </summary> | ||
public class DomainBuilder | ||
{ | ||
private readonly DomainRange[] ranges; | ||
private int index; | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="DomainBuilder"/> class. | ||
/// </summary> | ||
/// <param name="rangeCount">The amount of ranges to build.</param> | ||
public DomainBuilder(int rangeCount) | ||
{ | ||
ranges = new DomainRange[rangeCount]; | ||
index = 0; | ||
} | ||
|
||
/// <summary> | ||
/// Adds a range to the domain. | ||
/// </summary> | ||
/// <param name="configuration">The delegate to configure the domain range.</param> | ||
/// <returns>The builder.</returns> | ||
/// <exception cref="InvalidOperationException">The amount of added ranges exceeded the amount specified on the builder creation.</exception> | ||
public DomainBuilder AddRange(Action<DomainRangeBuilder> configuration) | ||
{ | ||
if (index >= ranges.Length) | ||
throw new InvalidOperationException(); // TODO: | ||
|
||
var builder = new DomainRangeBuilder(); | ||
configuration(builder); | ||
ranges[index++] = builder.Build(); | ||
|
||
return this; | ||
} | ||
|
||
/// <summary> | ||
/// Builds the domain of the function. | ||
/// </summary> | ||
/// <returns>The domain of the function.</returns> | ||
public Domain Build() | ||
=> new Domain(ranges); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
// Copyright (c) Dmytro Kyshchenko. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
||
namespace xFunc.Maths.Expressions.Domains; | ||
|
||
/// <summary> | ||
/// Represents a range of allowed values for the domain of function. | ||
/// </summary> | ||
public readonly struct DomainRange : IEquatable<DomainRange> | ||
{ | ||
private readonly NumberValue start; | ||
private readonly bool isStartInclusive; | ||
private readonly NumberValue end; | ||
private readonly bool isEndInclusive; | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="DomainRange"/> struct. | ||
/// </summary> | ||
/// <param name="start">The start of the range.</param> | ||
/// <param name="isStartInclusive">Determines whether the <paramref name="start"/> parameter is inclusive.</param> | ||
/// <param name="end">The end of the range.</param> | ||
/// <param name="isEndInclusive">Determines whether the <paramref name="end"/> parameter is inclusive.</param> | ||
public DomainRange(NumberValue start, bool isStartInclusive, NumberValue end, bool isEndInclusive) | ||
{ | ||
if ((start.IsInfinity && isStartInclusive) || | ||
(end.IsInfinity && isEndInclusive)) | ||
throw new InvalidOperationException(); // TODO: | ||
|
||
this.start = start; | ||
this.isStartInclusive = isStartInclusive; | ||
this.end = end; | ||
this.isEndInclusive = isEndInclusive; | ||
} | ||
|
||
/// <summary> | ||
/// Indicates whether <paramref name="left"/> range is equal to the <paramref name="right"/> range. | ||
/// </summary> | ||
/// <param name="left">The left range.</param> | ||
/// <param name="right">The right range.</param> | ||
/// <returns><c>true</c> if the <paramref name="left"/> range is equal to the <paramref name="right"/> range; otherwise, <c>false</c>.</returns> | ||
public static bool operator ==(DomainRange left, DomainRange right) | ||
=> left.Equals(right); | ||
|
||
/// <summary> | ||
/// Indicates whether <paramref name="left"/> range is not equal to the <paramref name="right"/> range. | ||
/// </summary> | ||
/// <param name="left">The left range.</param> | ||
/// <param name="right">The right range.</param> | ||
/// <returns><c>true</c> if the <paramref name="left"/> range is not equal to the <paramref name="right"/> range; otherwise, <c>false</c>.</returns> | ||
public static bool operator !=(DomainRange left, DomainRange right) | ||
=> !left.Equals(right); | ||
|
||
/// <inheritdoc /> | ||
public bool Equals(DomainRange other) | ||
=> start.Equals(other.start) && | ||
isStartInclusive == other.isStartInclusive && | ||
end.Equals(other.end) && | ||
isEndInclusive == other.isEndInclusive; | ||
|
||
/// <inheritdoc /> | ||
public override bool Equals(object? obj) | ||
=> obj is DomainRange other && Equals(other); | ||
|
||
/// <inheritdoc /> | ||
public override int GetHashCode() | ||
=> HashCode.Combine(start, isStartInclusive, end, isEndInclusive); | ||
|
||
/// <inheritdoc /> | ||
public override string ToString() | ||
{ | ||
var leftBracket = isStartInclusive ? '[' : '('; | ||
var rightBracket = isEndInclusive ? ']' : ')'; | ||
|
||
return $"{leftBracket}{start}; {end}{rightBracket}"; | ||
} | ||
|
||
/// <summary> | ||
/// Determines whether the <paramref name="value"/> number is in the range of domain. | ||
/// </summary> | ||
/// <param name="value">The number.</param> | ||
/// <returns><c>true</c>, if the <paramref name="value"/> number is in the range of domain, otherwise, <c>false</c>.</returns> | ||
public bool IsInRange(NumberValue value) | ||
=> CheckStart(value) && CheckEnd(value); | ||
|
||
private bool CheckStart(NumberValue value) | ||
=> isStartInclusive | ||
? start <= value | ||
: start < value; | ||
|
||
private bool CheckEnd(NumberValue value) | ||
=> isEndInclusive | ||
? value <= end | ||
: value < end; | ||
} |
Oops, something went wrong.