-
-
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.
Merge pull request #665 from sys27/bugfix/662-simplification
#662 - The simplification of trigonometric and inverse trigonometric functions is not correct
- Loading branch information
Showing
24 changed files
with
1,313 additions
and
196 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,84 @@ | ||
// Copyright (c) Dmytro Kyshchenko. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
||
using System.Diagnostics.CodeAnalysis; | ||
|
||
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) | ||
{ | ||
if (ranges is null || ranges.Length == 0) | ||
throw new ArgumentNullException(nameof(ranges)); | ||
|
||
for (var i = 0; i < ranges.Length - 1; i++) | ||
{ | ||
var left = ranges[i]; | ||
var right = ranges[i + 1]; | ||
|
||
if (right.Start < left.Start && right.End < left.End) | ||
throw new ArgumentException(Resource.DomainIsInvalid); | ||
} | ||
|
||
this.ranges = ranges; | ||
} | ||
|
||
/// <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.SequenceEqual(other.ranges); | ||
|
||
/// <inheritdoc /> | ||
public override bool Equals(object? obj) | ||
=> obj is Domain other && Equals(other); | ||
|
||
/// <inheritdoc /> | ||
[ExcludeFromCodeCoverage] | ||
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(Resource.DomainRangeExceeded); | ||
|
||
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); | ||
} |
Oops, something went wrong.