Comments (19)
So my idea was to run something like this piece of code
rationalize_real = function(num) {
if (Math.round(num) === num) return num;
var parts = num.toString().split('.');
return '(' + (parts[0]==='0' ? parts[1] : parts[0]+parts[1]) + '/1'
+ Array(parts[1].length+1).join('0') + ')';
}
to replace each number in the input by a rational to avoid any floating point operations in Algebrite. It would not change 1/3
, since only the 1
and the 3
would be passed to the function, but it would turn 0.5
into 5/10
and 3.3333
into 33333/10000
.
What is the more general case you mentioned?
Where should I best add the test cases?
from algebrite.
I'll look into the ReferenceError: Eval_display is not defined
problem.
In regards to getting text out of an Algebrite expression: .toString()
should do the job.
In regards to checking equivalences, here are some starting points:
Algebrite.equal(Algebrite.eval('x+x+x'),Algebrite.eval('3*x')); // 1
Algebrite.equal(Algebrite.eval('x+x+x+1'),Algebrite.eval('3*x')); // 0
Algebrite.eval('x+x+x == 3*x').toString(); // "1"
Algebrite.eval('x+x+x > 3*x').toString(); // "0"
Algebrite.eval('x+x+x + 1 > 3*x').toString(); // "1"
Note that indeed it's best, for more complex simplifications, to unleash "simplify" on both sides, otherwise for example this equivalence is not found:
Algebrite.equal(Algebrite.simplify('cos(x)^2 + sin(x)^2'),Algebrite.simplify('1')); // 1, not found without simplify
P.S.
Just to manage your expectations to determine equivalences: to do that in general is too much of a complex job for any CASs, so your mileage may vary.
P.P.S. longer version
...there can be many forms to an expression, finding a canonical form is not always possible or practical, and CASs can't practically try them all. Many equivalences (e.g. some famous ones are Ramanujan formulas who could draw amazing equivalences without always being sure of correctness or proof) took many years of mathematician's acumen to demonstrate (and development of new algorithms to be able to be handled by CASs, again related to Ramanujan see equivalences of nested radicals where a general algorithm was only found in 1989 by Susan Landau https://en.wikipedia.org/wiki/Nested_radical#Landau.27s_algorithm )
from algebrite.
I see now your work on https://graspablemath.com/ , I'd have been less verbose if I knew you are in the field :-)
Yes please if you find other cases you'd expect to work please let me know...
from algebrite.
Thank you for explaining!
I ended up using Algebrite.equal(Algebrite.simplify(expr1), Algebrite.simplify(expr2))
, which works great for the cases I'm concerned about!
For all cases, except... When I am comparing (1+1)^(1/3)
and (0.5*4)^(1/3)
, Algebrite tells me they are different. The reason is that (1+1)^(1/3)
simplifies to 2^(1/3)
, while (0.5*4)^(1/3)
simplifies to 1.25992
. Is there a straightforward solution to this? Maybe a way to disable simplifications that lose precision? Or casting real numbers back into integers?
from algebrite.
Using a float anywhere in an expression (0.5 in your example) makes the system calculate the approximate values.
You could:
- behind the scenes also force both sides to a float with "float" and check that the difference between them is really small.
- OR, more clean, we could add a way to have Algebrite to parse the floats in an expression and transform them into rationals in some circumstances (maybe a flag, or a "toRational" function or similar). But that float -> rationals mechanism would have to be implemented...
from algebrite.
Brilliant! Turning the floats into rationals as a first step will work perfectly! Something very naive like turning floats into (n*10^k)/(10^k)
will probably work fine. I'll do that on my side. Let me know if you want to integrate something like this into Algebrite.
from algebrite.
yes slightly byzantine though that it would work on 1/2 but not on 1/3 etc... You sure that you'll be working only with floats that will work? Would you consider doing the more general case (or are you in a pinch)?
On a separate note, It'd be safer to cover your use cases with tests so that I'm sure I'm not going to break them with coming versions... I.e. if you add them you'll be covered.
from algebrite.
handling the general case would mean introducing a notation for infinite digit sequences like 0.33333... (but sequences can be slightly more complex so might need to get more creative than just using the three dots ) and implementing the algorithm that finds out which rational creates the sequence. I can't link to it easily from iPhone but it should be rather compact.
...tests are in the test folder, try to see if there is a test file that fits the type of work you do.
from algebrite.
links for converting floats to rationals: https://rosettacode.org/wiki/Convert_decimal_number_to_rational and http://stackoverflow.com/questions/95727/how-to-convert-floats-to-human-readable-fractions
from algebrite.
The rosettacode link does not work for me, but the algorithm in the accepted answer from stackoverflow is neat!
What is the use case for this for an Algebrite user? I personally just needed a way to force exact integer-based calculations for initial expressions that contained floats. So in a way limiting the size of the denominator to make it more human-readable is exactly what I don't want :)
Is there a scenario where a user would actually want nice looking fraction approximations instead of real numbers or ugly fractions? I guess I can see it being useful in combination with some special notation to mark repeating sequences in the digits so the conversion between real notation and fraction notation is lossless. That's not part of the existing algorithm, though.
from algebrite.
With some euristics I think one can guess most human-entered floats of the type you seem to get as input.
I think it's intereating to have. Ideally I'll want to make an inverse symbolic calculator but one step at a time...
Maybe if you can tell what you expect people to present as input in your cases, I'm going to use that to do the euristics.
The problem with the special notation for the exact representation is that a) floats don't have that notation and b) can we expect users who can't be bothered to input the rational in the first place to then use the special notation of the exact decimal expansion?
from algebrite.
so, to the point, the use case for this is to straighten "lazily"-entered floats into guessed rationals. 0.5 to 1/2 but also 0.33333 to 1/3. So in other words it guesses normal textbook fractions, nothing too convoluted.
from algebrite.
so the name of the function could be, aptly, something like "guessSimpleFraction" . It's a convenience for input, nothing more.
from algebrite.
There's a nice algorithm here by John Kennedy to convert double -> rational
https://github.com/geogebra/geogebra/blob/master/common/src/main/java/org/geogebra/common/kernel/algos/AlgoFractionText.java
If you also want to convert double -> surd then you can use the PSLQ algorithm, eg
https://github.com/geogebra/geogebra/blob/master/common/src/main/java/org/geogebra/common/kernel/cas/AlgoSurdText.java
from algebrite.
Just realised I've written a JavaScript version which you're welcome to use under MIT licence
`
DecimalToFraction: method(function(decimal, AccuracyFactor) {
var FractionNumerator, FractionDenominator;
var DecimalSign;
var Z;
var PreviousDenominator;
var ScratchValue;
var ret = [0,0];
if (isNaN(decimal)) return ret; // return 0/0
if (decimal === Infinity) {
ret[0] = 1;
ret[1] = 0 ; // 1/0
return ret;
}
if (decimal === -Infinity) {
ret[0] = -1;
ret[1] = 0; // -1/0
return ret;
}
if (decimal < 0.0) DecimalSign = -1.0; else DecimalSign = 1.0;
decimal = Math.abs(decimal);
if (Math.abs(decimal - Math.floor(decimal)) < AccuracyFactor) { // handles exact integers including 0
FractionNumerator = decimal * DecimalSign;
FractionDenominator = 1.0;
ret[0] = FractionNumerator;
ret[1] = FractionDenominator;
return ret;
}
if (decimal < 1.0E-19) { // X = 0 already taken care of
FractionNumerator = DecimalSign;
FractionDenominator = 9999999999999999999.0;
ret[0] = FractionNumerator;
ret[1] = FractionDenominator;
return ret;
}
if (decimal > 1.0E19) {
FractionNumerator = 9999999999999999999.0 * DecimalSign;
FractionDenominator = 1.0;
ret[0] = FractionNumerator;
ret[1] = FractionDenominator;
return ret;
}
Z = decimal;
PreviousDenominator = 0.0;
FractionDenominator = 1.0;
do {
Z = 1.0/(Z - Math.floor(Z));
ScratchValue = FractionDenominator;
FractionDenominator = FractionDenominator * Math.floor(Z) + PreviousDenominator;
PreviousDenominator = ScratchValue;
FractionNumerator = Math.floor(decimal * FractionDenominator + 0.5); // Rounding Function
} while ( Math.abs((decimal - (FractionNumerator /FractionDenominator))) > AccuracyFactor && Z !== Math.floor(Z));
FractionNumerator = DecimalSign*FractionNumerator;
ret[0] = FractionNumerator;
ret[1] = FractionDenominator;
return ret;
})
`
from algebrite.
https://web.archive.org/web/20111027100847/http://homepage.smc.edu/kennedy_john/DEC2FRAC.PDF
from algebrite.
thanks a lot! First shot at this: 11013a3 . I'm going to credit John Kennedy immediately in the next commit.
from algebrite.
credited
from algebrite.
approxratio now works on entire expressions:
https://github.com/davidedc/Algebrite/blob/eb1ed2e6a3720435f60ad88100329d58b733b88f/tests/approxratio.coffee . So this should cater for typical ratios entered as floats. Hopefully most people would still enter irrational and transcendental numbers with an appropriate expression rather than as a float. Those other cases to be picked up later.
from algebrite.
Related Issues (20)
- power precedence in printlatex
- i^5 returns -i, but should be i
- Simplification steps?
- Returning numerical values
- nroots and roots do not work for polynomials with non-integer coefficients
- Solving Boolean expressions
- Solving systems of equations
- Absolute value syntax errors
- Solving equations involving fractions
- Simplify
- GUI for user to edit/enter the equation in HTML
- Testing equivalance could be more smart, easily
- Update NPM version
- cann't simpifay apk
- the order of the powers of the polynomial is reversed HOT 1
- How to solve equations? HOT 2
- How to identify if an expression given by a human is in its simplified form HOT 4
- Is there some kind of AST ? HOT 1
- draw function is needed HOT 1
- Can't return numerical results < 1e-6. Can't substitute variables with scientific notation
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from algebrite.