> For the complete documentation index, see [llms.txt](https://jona-projects.gitbook.io/kiwicalc/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://jona-projects.gitbook.io/kiwicalc/symbolic-computation/fastpoly.md).

# FastPoly

The `FastPoly` class serves as an alternative to the `Poly` class when handling with polynomials. For most simple cases, it should be considerably faster and memory performant, but it's still rather limited.

#### Advantages

There are several advantages of using the `FastPoly` class instead of the `Poly` class in certain cases.

* Faster - faster root-finding, addition, and subtraction when the polynomial is of a relatively small degree.
* More memory performant - For most simple cases, the `FastPoly` class uses less memory than the `Poly` class. That stems from the difference between the storage of the two ways: a `Poly` object contains a collection of `Mono` objects, while a `FastPoly` object stores the coefficients of the different variables. In addition, `Poly` objects tend to store large amounts of memory when containing a large number of expressions, while `FastPoly` expressions will store lower amounts of memory, as long the degree of of the polynomial will be low.

#### Disadvantages

* Slower and less memory performant on polynomials with higher degrees. As mentioned earlier, `PolyFast` stores collections of coefficients, so a polynomial of degree 1000 will be represented with a 1000 coefficients. Storing such big amounts of memory can be inefficient in larger compuations.
* Still partially implemented - As for this version, `FastPoly` still doesn't support multiplying and dividing polynomials. Also, there is no support yet for powers with the `**` operator.
* Incompatible with `IExpression` - Most expressions in KiwiCalc inherit from the `IExpression` interface. That way, they are more compatible with each other, and able to interact with each other. However, `FastPoly` isn't fully compatible with it yet.
* No Support for 'mixed' expressions - Currently, the `FastPoly` class doesn't support expressions with expressions such as \`xy\`. For instance, you could represent the expression $$x^2 + 2xy + y^2$$ via the `Poly` class, but not with the `FastPoly` class.

#### Conclusion

While `FastPoly` tends to be much faster and performant on simple polynomials and polynomials with many expressions than `Poly`, it takes a lot of of memory for polynomials with higher degrees, and it is still quite limited with its features. Therefore, it would be best to use FastPoly on polynomials with lower degrees when not needing sophisticated features and compatibility with other types of expressions.

#### Properties

* `variables`(list) - a copy of a list of the variables that appear in the expression. For instance, the list will be `['x', 'y']` for the expression $$x^2 + 2y - 7$$.
* `num_of_variables`(int) - get the number of variables in the expression without fetching a copy of the list of variables.
* `variables_dict`(dict) - The polynomial is represented internally in a dictionary.
* `degree(Union[float, dict])` - The highest power in the expression. If the polynomial contains only 1 variable, the result will be integer. For instance, for the polynomial $$x^2 + 2x + 1$$ the result would be `2`. For expressions with several variables, a dictionary with the highest powers of each variable will be returned. For example, for the polynomial  $$2x^3 - 2y + 5y^2 + 1$$, the result would be `{'x':[2,0,0], 'y':[5,-2], 'free':1}`.

#### Creating a `FastPoly` object.

There are several ways to create a `PolyFast` object.

1. Entering a string- The most prominent and easiest method to create a new `PolyFast` object is by entering a string that represents a polynomial. The string will be parsed internally into a dictionary and will be stored in the object. For example:

   ```python
   # creating a PolyFast object
   fast_poly = FastPoly("3x^5 - 2y^2 + 3x + 14")
   ```

   You can also specify the variables in the expression to speed us the parsing of the string.

   <pre class="language-python"><code class="lang-python"><strong>fast_poly = FastPoly("3x^5 - 2y^2 + 3x + 14", variables=('x', 'y'))   
   </strong></code></pre>
2. Entering the parsed dictionary directly- As mentioned before, the polynomial is represented internally via a dictionary. Each key-value pair in the dictionary is a variable that appears in the expression and a list of its coefficients. In addition, a special key `'free'` is added to the dictionary to represent the free number. For instance, the dictionary for the expression $$x^2+2x+6$$ will be:

   ```python
   {'x':[1,2], 'free':6}                      
   ```

   And the dictionary for the expression $$2x^3+y^3+7$$ will be

   ```python
   {'x':[2,0,0], 'y':[1,0,0], 'free':7}                       
   ```

   You can enter a dictionary in this syntax in order to create a `PolyFast` object in a shorter time. For example, this is how we can create the expression $$2n^4-32$$

   ```python
   FastPoly({'n':[2,0,0,0], 'free':-32})      
   ```
3. Entering a `list` or `tuple` of coefficients- You can create a polynomial with 1 variable by entering its coefficients and the name of the variable. If the name of the variable isn't given, the default is $$x$$ For instance, the coefficients of the expression $$n^2+2n+1$$ are `[1,2,1]`, so you can create the expression in the following way:

   ```python
   fast_poly = FastPoly([1,2,1], variables=('n',))
                               
   ```

#### Adding and Subtracting

You can add and subtract `FastPoly` objects via the \`+\` and \`-\` operators. For example:

```python
poly1 = FastPoly("2x^3 + 5x -7")
poly2 = FastPoly("x^2 + 4y^2 - x^3 + 5x + 6")
print(poly1+poly2)
#output: 'x^3+x^2+10x+4y^2-1'
                    
```

```python
poly1 = FastPoly("2x^3 + 6x^2 + 5")
poly2 = FastPoly("x^4 + x^3 - 5x^2 + 6")
print(poly1-poly2)
#output: '-x^4+x^3+11x^2-1' 
                    
```

#### Finding the roots of the polynomial

If the polynomial has only 1 variable, you can use the `roots()` method to find its roots. For instance:

```python
fast_poly = FastPoly("x^4+8x^3+11x^2-20x")
print(fast_poly.roots())
# output: [0j, (1+0j), (-5+0j), (-4+0j)]
                        
                    
```

#### `assign()`

You can assign values to variables via the `assign()` method. For example:

```python
my_poly = FastPoly("x^2 + y^2")
my_poly.assign(x=5)
print(my_poly)
# output: 'y^2+25'
                    
```

#### `when()`

You can an assigned copy of the object via the `when()` method. For example:

```python
my_poly = FastPoly("x^2 + y^2")
print(my_poly.when(x=5))
print(my_poly)
# output: 'y^2+25'
# 'x^2 + y^2' 
                    
```

#### `try_evaluate()`

You can try to evaluate a polynomial into an int or float via the `try_evaluate()`

method. If not possible, `None` will be created. For instance:

```python
poly1 = FastPoly("5")
poly2 = FastPoly("x^2 + 6x + 8")
print(poly1.try_evaluate())
print(poly2.try_evaluate())
#output: '5.0'
#'None'
                    
```

#### `plot()`

You can plot `FastPoly` object with 1 or 2 variables in 2D or 3D respectively via the `plot()` method. Here is a [detailed explanation](broken://pages/pTRMHHLCs8F75wD3kRE1) about the method. For example:

```python
fast_poly = FastPoly("x^3 - 2x + 1")
fast_poly.plot()
                    
```

#### `scatter()`

you can scatter `FastPoly` objects with 1 or two variables in 2D or 3D respectively via the `scatter()` method. For instance:

```python
fast_poly = FastPoly("x^3 - 2x + 1")
fast_poly.scatter()
                    
```
