Skip to content

Commit

Permalink
More examples and fixed typos in documentation (#54)
Browse files Browse the repository at this point in the history
  • Loading branch information
sakari-malkki authored Dec 17, 2024
1 parent 0cfa355 commit 91be0d0
Show file tree
Hide file tree
Showing 3 changed files with 163 additions and 13 deletions.
8 changes: 4 additions & 4 deletions Px.Utils/Operations/DivisionMatrixFunctionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,10 @@ public static Matrix<TData> DivideSubsetBySelectedValue<TData>(this Matrix<TData
/// <param name="dividerValueCode">The set of datapoints defined by this dimension value
/// will be used to divide the corresponding datapoints defined by <paramref name="targetMap"/></param>
/// <returns>A new <see cref="Matrix{TData}"/> object that contais the results of the operation.</returns>
public static async Task<Matrix<TData>> DivideSubsetBySelectedValueAsync<TData>(this Matrix<TData> input, IDimensionMap targetMap, string baseValueCode)
public static async Task<Matrix<TData>> DivideSubsetBySelectedValueAsync<TData>(this Matrix<TData> input, IDimensionMap targetMap, string dividerValueCode)
where TData : IDivisionOperators<TData, TData, TData>, IMultiplicativeIdentity<TData, TData>
{
return await Task.Factory.StartNew(() => DivideSubsetBySelectedValue(input, targetMap, baseValueCode));
return await Task.Factory.StartNew(() => DivideSubsetBySelectedValue(input, targetMap, dividerValueCode));
}

/// <summary>
Expand All @@ -96,10 +96,10 @@ public static async Task<Matrix<TData>> DivideSubsetBySelectedValueAsync<TData>(
/// <param name="dividerValueCode">The set of datapoints defined by this dimension value
/// will be used to divide the corresponding datapoints defined by <paramref name="targetMap"/></param>
/// <returns>A new <see cref="Matrix{TData}"/> object that contais the results of the operation.</returns>
public static async Task<Matrix<TData>> DivideSubsetBySelectedValueAsync<TData>(this Task<Matrix<TData>> input, IDimensionMap targetMap, string baseValueCode)
public static async Task<Matrix<TData>> DivideSubsetBySelectedValueAsync<TData>(this Task<Matrix<TData>> input, IDimensionMap targetMap, string dividerValueCode)
where TData : IDivisionOperators<TData, TData, TData>, IMultiplicativeIdentity<TData, TData>
{
return await DivideSubsetBySelectedValueAsync(await input, targetMap, baseValueCode);
return await DivideSubsetBySelectedValueAsync(await input, targetMap, dividerValueCode);
}

private static TData Divide<TData>(TData a, TData b) where TData : IDivisionOperators<TData, TData, TData>, IMultiplicativeIdentity<TData, TData>
Expand Down
6 changes: 3 additions & 3 deletions Px.Utils/Operations/SumMatrixFunctionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,9 @@ public async static Task<Matrix<TData>> AddConstantToSubsetAsync<TData>(this Mat
/// <typeparam name="TData">Type of the data values in the matrix, must implement
/// <see cref="IAdditionOperators{TSelf, TOther, TResult}"/> and <see cref="IAdditiveIdentity{TSelf, TResult}"/></typeparam>
/// <param name="input">The source matrix for the operation</param>
/// <param name="targetMap">Defines the values to wich the constant will be added.</param>
/// <param name="valueToAdd">The contant to be added.</param>
/// <returns>A new <see cref="Matrix{TData}"/> object that contais the results of the additions.</returns>
/// <param name="targetMap">Defines the values to which the constant will be added.</param>
/// <param name="valueToAdd">The constant to be added.</param>
/// <returns>A new <see cref="Matrix{TData}"/> object that contains the results of the additions.</returns>
public async static Task<Matrix<TData>> AddConstantToSubsetAsync<TData>(this Task<Matrix<TData>> input, IMatrixMap targetMap, TData valueToAdd)
where TData : IAdditionOperators<TData, TData, TData>, IAdditiveIdentity<TData, TData>
{
Expand Down
162 changes: 156 additions & 6 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Extending the library with a new features should be as easy as possible and ever
## Installation
Px.Utils can be installed using .NET CLI or NuGet Package Manager.

### .NET CL
### .NET CLI
#### Latest
```bash
dotnet add package Px.Utils
Expand Down Expand Up @@ -106,6 +106,16 @@ There are no limits for the number or size of dimensions. But it is important to
```GetTransform(IMatrixMap map)``` method can be used to take a subset of the the matrix and/or change the order of the dimensions or the dimension values.
It creates a new mutable deep copy of the matrix that have the structure defined by the map parameter. The data array will also be copied and reordered based on the map.

##### Example
```csharp
MatrixMap map = new(
[
new DimensionMap("variable-0", ["variable-0_value-0", "variable-0_value-2", "variable-0_value-4"]),
new DimensionMap("variable-1", ["variable-1_value-0", "variable-1_value-2"])
]);
Matrix<DecimalDataValue> output = matrix.GetTransform(map);
```

#### ```MatrixMap : IMatrixMap```
This is a minimal way to represent the structure of the metadata. Does not contain any other information than the dimension and dimension value codes.
The ```IReadOnlyMatrixMetadata``` also implements the ```IMatrixMap``` interface.
Expand All @@ -130,17 +140,24 @@ They both implement the ```IReadOnlyList<IReadOnlyDimensionValue>``` interface,
Differs from the base class by having values of type ```ContentDimensionValue```.

#### ```TimeDimension : Dimension```
Shares the same value type as the base class, but has additional properties in the dimension level metadata.
Shares the same value type as the base class, but has an additional property in the dimension level metadata:
- ```Interval``` (```TimeDimensionInterval```[enum]): Represents the interval of the time dimension. Can be either Year, HalfYear, Quarter, Month, Week, Other or Irregular.

TimeDimension's Type (```DimensionType```[enum]) is always Time.

#### ```DimensionValue : IReadOnlyDimensionValue```
Represents the dimension value level metadata of a px-file. This is a base class for all dimension values. Each value has a unique string code among the values in the dimension.

#### ```ContentDimensionValue : DimensionValue```
Dimension value that contais content dimension value specific metadata.
Dimension value that contais content dimension value specific metadata properties:
- ```Unit``` (```MultilanguageString```): Stores the unit associated with the content dimension value (such as "EUR" or "%") as a multilanguage string.
- ```LastUpdated``` (DateTime): Stores the date and time of the last updated associated with the content dimension value.
- ```Precision``` (int): Stores the precision - the number of decimal places - of the content dimension value.

#### ```MetaProperty```
Px.Utils supports reading any metadata properties that follow the px file syntax. The properties are stored in a ```Dictionary<string, MetaProperty>``` collection called ```AdditionalProperties``` where the dictionary key is the property keyword.
The base class ```MetaProperty``` is abstract and each supported property type has its own class that inherits from it.
Currently supported property types (represented by ```MetaPropertyType``` enum) and their respective classes are: ```Text``` (```StringProperty```), ```MultilanguageText``` (```MultilanguageStringProperty```), ```TextArray``` (```StringListProperty```), ```MultilanguageTextArray``` (```MultilanguageStringListProperty```), ```Numeric``` (```NumericProperty```) and ```Boolean``` (```BooleanProperty```).

### Data models
```IDataValue``` is an interface for the data points that defines the basic computation methods for the data points. See the Computing section for more information.
Expand All @@ -167,12 +184,26 @@ Validator classes implement either ```IPxFileStreamValidator``` or ```IPxFileStr
Custom validator objects can be injected by calling the SetCustomValidatorFunctions or SetCustomValidators methods of the PxFileValidator object. Custom validators must implement either the IPxFileValidator or IPxFileValidatorAsync interface. Custom validation methods are stored in CustomSyntaxValidationFunctions and CustomContentValidationFunctions objects for syntax and content validation processes respectively.
Once the PxFileValidator object is instantiated, either the Validate or ValidateAsync method can be called to validate the px file. The Validate method returns a ValidationResult object that contains the validation results as a key value pair containing information about the rule violations.

##### Example
```csharp
PxFileValidator validator = new PxFileValidator();
ValidationResult result = validator.Validate(fileStream, "path/to/file.px", Encoding.UTF8);
ValidationResult asyncResult = await validator.ValidateAsync(fileStream, "path/to/file.px", Encoding.UTF8, cancellationToken: cancellationToken);
```

#### SyntaxValidator : IPxFileStreamValidator, IPxFileStreamValidatorAsync
```SyntaxValidator``` is a class that validates the syntax of a px file's metadata. It needs to be run before other validators, because both the ```ContentValidator``` and ```DataValidator``` require information from the ```SyntaxValidationResult``` object that ```SyntaxValidator``` ```Validate()``` and ```ValidateAsync()``` methods return.
The class can be instantiated with the following parameters:
- conf (PxFileConfiguration, optional): Object that contains px file configuration.
- customValidationFunctions (CustomSyntaxValidationFunctions, optional): Object that contains custom validation functions for the syntax validation process.

##### Example
```csharp
SyntaxValidator validator = new SyntaxValidator();
SyntaxValidationResult result = validator.Validate(fileStream, "path/to/file.px", Encoding.UTF8);
SyntaxValidationResult asyncResult = await validator.ValidateAsync(fileStream, "path/to/file.px", Encoding.UTF8, cancellationToken: cancellationToken);
```

#### ContentValidator : IValidator
```ContentValidator``` class validates the integrity of the contents of a px file's metadata. It needs to be run after the ```SyntaxValidator```, because it requires information from the ```SyntaxValidationResult``` object that ```SyntaxValidator``` ```Validate()``` and ```ValidateAsync()``` methods return.
The class can be instantiated with the following parameters:
Expand All @@ -182,14 +213,34 @@ The class can be instantiated with the following parameters:
- customContentValidationFunctions (CustomContentValidationFunctions, optional): Object that contains custom functions for validating the px file metadata contents.
- conf (PxFileConfiguration, optional): Object that contains px file configuration.

##### Example
```csharp
Encoding encoding = Encoding.UTF8;
SyntaxValidator syntaxValidator = new SyntaxValidator();
SyntaxValidationResult syntaxResult = syntaxValidator.Validate(fileStream, "path/to/file.px", encoding);
ContentValidator validator = new ContentValidator("path/to/file.px", encoding, syntaxResult.Result);
ValidationResult result = validator.Validate();
```

#### DataValidator : IPxFileStreamValidator, IPxFileStreamValidatorAsync
```DataValidator``` class is used to validate the data section of a px file. It needs to be run after the ```SyntaxValidator```, because it requires information from both the ```SyntaxValidationResult``` and ```ContentValidationResult``` objects that ```SyntaxValidator``` and ```ContentValidator``` ```Validate()``` and ```ValidateAsync()``` methods return.
```DataValidator``` class is used to validate the data section of a px file. It needs to be run after the ```SyntaxValidator``` and ```ContentValidator``` because it requires information provided by the ```SyntaxValidationResult``` and ```ContentValidationResult``` objects that the ```SyntaxValidator``` and ```ContentValidator``` ```Validate()``` and ```ValidateAsync()``` methods return.
The class can be instantiated with the following parameters:
- rowLen (int): Length of one row of Px file data. ContentValidationResult object contains this information.
- numOfRows (int): Amount of rows of Px file data. This information is also stored in ContentValidationResult object.
- startRow (long): The row number where the data section starts. This information is stored in the SyntaxValidationResult object.
- conf (PxFileConfiguration, optional): Configuration for the Px file

##### Example
```csharp
Encoding encoding = Encoding.UTF8;
SyntaxValidator syntaxValidator = new SyntaxValidator();
SyntaxValidationResult syntaxResult = syntaxValidator.Validate(fileStream, "path/to/file.px", encoding);
ContentValidator contentValidator = new ContentValidator("path/to/file.px", encoding, syntaxResult.Result);
ValidationResult contentResult = contentValidator.Validate();
DataValidator validator = new DataValidator(contentResult.DataRowLength, contentResult.DataRowAmount, syntaxResult.DataStartRow);
ValidationResult result = validator.Validate(fileStream, "path/to/file.px", encoding);
```

#### DatabaseValidator : IValidator, IValidatorAsync
Whole px file databases can be validated using ```DatabaseValidator``` class. Validation can be done by using the blocking ```Validate()``` or asynchronous ```ValidateAsync()``` methods. ```DatabaseValidator``` class can be instantiated using the following parameters:
- directoryPath (string): Path to the database root
Expand All @@ -202,30 +253,129 @@ Whole px file databases can be validated using ```DatabaseValidator``` class. Va
Database validation process validates each px file within the database and also the required structure and consistency of the database languages and encoding formats. The return object is a ```ValidationResult``` object that contains ```ValidationFeedback``` objects gathered during the validation process.
The database needs to contain alias files for each language used in the database for each folder that contains either subcategory folders or px files. If either languages or encoding formats differ between alias or px files, warnings are generated.

##### Example
```csharp
DatabaseValidator validator = new DatabaseValidator("path/to/database");
ValidationResult result = validator.Validate();
ValidationResult asyncResult = await validator.ValidateAsync(cancellationToken);
```

### Computing

```Matrix<TData>``` class has a set of extension methods for performing basic computations for the datapoints.

Values of dimensions can be summed or multiplied together to new values. If the original matrix has the following structure:

|| col0-0 || col0-1 || col0-2 ||
||-----------|-----------|-----------|-----------|-----------|-----------|
|| col1-0 | col1-1| col1-0 | col1-1| col1-0 | col1-1 |
|row0-0| 0 | 1 | 2 | 3 | 4 | 5 |
|row0-1| 6 | 7 | 8 | 9 | 10 | 11 |
|row0-2| 12 | 13 | 14 | 15 | 16 | 17 |

If we sum the row0 dimension's values 1 and 2 together to form a new value "rowSum", the resulting matrix will look like this:

|| col0-0 || col0-1 || col0-2 ||
||-----------|-----------|-----------|-----------|-----------|-----------|
|| col1-0 | col1-1| col1-0 | col1-1| col1-0 | col1-1 |
|row0-0| 0 | 1 | 2 | 3 | 4 | 5 |
|row0-1| 6 | 7 | 8 | 9 | 10 | 11 |
|row0-2| 12 | 13 | 14 | 15 | 16 | 17 |
|rowSum | 18 | 20 | 22 | 24 | 26 | 28 |

#### Sum
```SumToNewValue<TData>()``` computes sums of datapoints defined by a subset of values from a given dimension.
The method takes a new dimension value as a parameter that will define the resulting values.
The method also has an asyncronous variant ```SumToNewValueAsync<TData>()```.
The method also has an asyncronous variant ```SumToNewValueAsync<TData>()```.

##### Example
```csharp
DimensionValue newDimensionValue = new("rowSum", new("en", "Sum value"));
DimensionMap map = new("row0", ["row0-1", "row0-2"]);
Matrix<DecimalDataValue> output = matrix.SumToNewValue(newDimensionValue, map);
```

```AddConstantToSubset<TData>()``` adds a constant to a subset of datapoints. Also has an asynchronous variant ```AddConstantToSubsetAsync<TData>()```.

##### Example
```csharp
IMatrixMap map = new MatrixMap([
new DimensionMap("col0", ["col0-0"]),
new DimensionMap("col1", ["col1-0", "col1-1"]),
]);

Matrix<DecimalDataValue> output = matrix.AddConstantToSubset(map, 5);
```

#### Multiplication
```MultiplyToNewValue<TData>()``` computes products of datapoints defined by a subset of values from a given dimension.
The method takes a new dimension value as a parameter that will define the resulting values.
The method also has an asyncronous variant ```MultiplyToNewValueAsync<TData>()```.

##### Example
```csharp
DimensionValue newDimensionValue = new("rowProduct", new("en", "Product value"));
DimensionMap map = new("row0", ["row0-1", "row0-2"]);
Matrix<DecimalDataValue> output = matrix.MultiplyToNewValue(newDimensionValue, map);
```

```MultiplySubsetByConstant<TData>()``` Multiply a subset of datapoints by a constant. Also has an asynchronous variant ```MultiplySubsetByConstantAsync<TData>()```.

##### Example
```csharp
IMatrixMap map = new MatrixMap([
new DimensionMap("col0", ["col0-0"]),
new DimensionMap("col1", ["col1-0", "col1-1"]),
]);

Matrix<DecimalDataValue> output = matrix.MultiplySubsetByConstant(map, 5);
```


#### Division
```DivideSubsetBySelectedValue()``` divides a subset of datapoints defined by values from one dimension with datapoints defined by a value from the same dimension.
```DivideSubsetBySelectedValue<TData>()``` divides a subset of datapoints defined by values from one dimension with datapoints defined by a value from the same dimension.
Also has an asyncronous variant ```DivideSubsetBySelectedValueAsync()```

If the original matrix has the following structure:

|| col0-0 || col0-1 || col0-2 ||
||-----------|-----------|-----------|-----------|-----------|-----------|
|| col1-0 | col1-1| col1-0 | col1-1| col1-0 | col1-1 |
|row0-0| 0 | 1 | 2 | 3 | 4 | 5 |
|row0-1| 6 | 7 | 8 | 9 | 10 | 11 |
|row0-2| 12 | 13 | 14 | 15 | 16 | 17 |
|rowSum | 18 | 20 | 22 | 24 | 26 | 28 |

And we divide row dimension values row0-1 and row0-2 by rowSum the resulting matrix will look like this:

|| col0-0 || col0-1 || col0-2 ||
||-----------|-----------|-----------|-----------|-----------|-----------|
|| col1-0 | col1-1| col1-0 | col1-1| col1-0 | col1-1 |
|row0-0| 0 | 1 | 2 | 3 | 4 | 5 |
|row0-1| 0.33 | 0.35 | 0.36 | 0.38 | 0.39 | 0.41 |
|row0-2| 0.67 | 0.65 | 0.64 | 0.63 | 0.61 | 0.59 |
|rowSum | 18 | 20 | 22 | 24 | 26 | 28 |

##### Example
```csharp
DimensionMap map = new("row0", ["row0-1", "row0-2"]);

Matrix<DecimalDataValue> output = matrix.DivideSubsetBySelectedValue(map, "rowSum");
```

```DivideSubsetByConstant<TData>()``` Divide a subset of datapoints by a constant. Also has an asynchronous variant ```DivideSubsetByConstantAsync<TData>()```.

##### Example
```csharp
IMatrixMap map = new MatrixMap([
new DimensionMap("col0", ["col0-0"]),
new DimensionMap("col1", ["col1-0", "col1-1"]),
]);

Matrix<DecimalDataValue> output = matrix.DivideSubsetByConstant(map, 2);
```


#### General

```ApplyOverDimension<TData>()``` Generatas a new set datapoints by applying a function to datapoints defined by a subset of values from one dimension.
Expand Down

0 comments on commit 91be0d0

Please sign in to comment.