Я заметил, что калькуляторы и графические программы, такие как Desmos, Geogebra или Google (поиск в Google x ^ (1/3)) должны иметь модифицированную версию функции Math.pow (), которая позволяет им строить некоторые отрицательные и дробные основания показатели, которые в противном случае были бы неопределенными, используя обычную функцию Math.pow ().
Я пытаюсь воссоздать эту модифицированную функцию pow, чтобы я мог построить отсутствующие участки графиков, например, $ x ^ {\ frac {1} {3}} $, где $ x <0 $ </p>
Моя попытка
Я не знаю, как эта модифицированная функция pow называется в компьютерной науке или математике, поэтому я не могу найти ссылки, которые помогли бы создать надежную и оптимизированную версию. Вместо этого я попытался создать свою собственную версию с помощью класса Fraction из библиотеки Apache math3, чтобы определить некоторые условные операторы, например, когда числитель и знаменатель являются четными или нечетными для дробных показателей.
В моей версии есть несколько проблем, которые я опишу, и в них могут отсутствовать некоторые дополнительные условия, которые я не рассмотрел и которые могут привести к ошибкам.
/* Main Method */
public static void main(String[] args) {
double xmin = -3;
double xmax = 3;
double epsilon = 0.011;
/* print out x,y coordinates for plot */
for (double x = xmin; x <= xmax; x += epsilon){
System.out.println(x+","+f(x));
}
}
/* Modified Power Function*/
private static double pow2(double base, double exponent){
boolean negativeBase = base < 0;
/* exponent is an integer and base non-negative */
if (exponent == ((int) exponent) && !negativeBase){
/* use regular pow function */
return Math.pow(base, exponent);
}
Fraction fraction;
try {
fraction = new Fraction(exponent, 1000); /* maxDenominator of 1000 for speed */
} catch (FractionConversionException e){
return Double.NaN;
}
/* updated: irrational exponent */
if (exponent != fraction.doubleValue()){
/* handles irrational exponents like π which cannot be reduced to fractions.
* depends heavily on the maxDenominator value set above.
* With a maxDenominator of 1000, fractions like 1/33333 who's denominator has greater then 4 digits
* will be considered as irrational. To avoid this, increase maxDenominator to 10000 but will slow down performance.
* That's the trade off with this part of the algorithm.
* Also this condition helps clear up a lot the mess on a plot.
* If the plot is centered at exactly origin (0,0) the messy artifacts may appear, but by offsetting
* the view of the plot slightly from the origin will make it disappear
* or maybe it has more to do with the stepsize epsilon (0.01 (clean number) vs 0.011 (irregular number))
* */
return Math.pow(base, exponent);
}
if (fraction.getDenominator() % 2 == 0){
/* if even denominator */
if (negativeBase){
return Double.NaN;
}
} else {
/* if odd denominator, allows for negative bases */
if (negativeBase){
if (fraction.getNumerator() % 2 == 0){
/* if even numerator
* (-base)^(2/3) is the same as ((-base)^2)^(1/3)
* any negative base squared is positive */
return Math.pow(-base, exponent);
}
/* return negative answer, make base and exponent positive */
return -Math.pow(-base, exponent);
}
}
return Math.pow(base, exponent);
}
/* Math function */
private static double f(double x){
/* example f(x) = x^(1/x) */
return pow2(x, (double) 1/x);
}
Выпуск № 1
Для обеих проблем я буду использовать математическую функцию $ f (x) = x ^ {\ frac {1} {x}} $ в качестве примера для графика, который демонстрирует обе проблемы - первая из них - FractionConversionException это вызвано наличием большого значения для показателя степени. Эта ошибка произойдет, если значение epsilon в моем коде будет изменено на 0.1, но, похоже, избежать ошибки при шаге epsilon 0.11. Я не уверен, как решить это правильно, но, глядя в класс Fraction, где он генерирует FractionConversionException, он использует условный оператор, который я мог бы скопировать в свою функцию pow2 () и заставить его вернуть NaN с кодом ниже. Но я не уверен, что это правильно!
long overflow = Integer.MAX_VALUE;
if (FastMath.abs(exponent) > overflow) {
return Double.NaN;
}
РЕДАКТИРОВАТЬ: Добавление оператора try / catch для создания экземпляра класса Fraction и возврата NaN в предложении catch представляется хорошим временным решением. Вместо приведенного выше кода.
Выпуск № 2
Построение математической функции $ f (x) = x ^ {\ frac {1} {x}} $ создает грязный участок слева, где $ x <0 $, см. Изображение ниже </p>

в отличие от того, как оно должно выглядеть
https://www.google.com/search?q=x^(1%2Fx)
Я не знаю, как избавиться от этого беспорядка, поэтому, где $ x <0 $, он должен быть неопределенным (NaN), в то же время позволяя функции pow2 () по-прежнему отображать такие функции, как $ x ^ {\ frac { 1} {3}} $, $ x ^ {\ frac {2} {3}} $, $ x ^ {x} $ и т. Д. * </p>
Я также не уверен, что установить maxDenominator при создании экземпляра объекта Fraction для хорошей производительности, не влияя при этом на результаты графика. Возможно, существует более быстрый алгоритм преобразования десятичной дроби в дробь, хотя я думаю, что Apache math3, вероятно, очень оптимизирован.
Edit:
Выпуск 3
Я забыл рассмотреть иррациональные показатели, потому что я был слишком поглощен аккуратными фракциями. Мой алгоритм не работает для иррациональных показателей, таких как π, и строит две версии графа вместе. Из-за того, как класс Fraction округляет показатель степени, некоторые знаменатели считаются четными и нечетными. Возможно, при условии, что если иррациональный показатель не равен доле, вместо этого нужно вернуть NaN. Просто быстро протестировал это условие, пришлось добавить условие absoluteBase, которое переворачивает график в правильном направлении. Нужно сделать дальнейшее тестирование, но может быть идея.
Edit2: после тестирования он должен фактически вернуть обычную функцию pow () вместо NaN, чтобы обработать условия для иррациональных показателей (см. Обновленный код для модифицированной степенной функции), а также этому подходу неожиданно удается избавиться от большей части беспорядок, выделенный в выпуске № 2, так как я считаю, что в интервале больше иррациональных чисел, чем рациональных чисел, которые исключаются алгоритмом, что делает его менее плотным и труднее соединить две точки в линию, чтобы появиться на графике.
if (exponent != fraction.doubleValue() && negativeBase){
return Double.NaN;
}
Дополнительный вопрос
Является ли точным представление / представление этих данных функции, как это делают большинство современных графических программ (упомянутых выше), или это действительно вводит в заблуждение, учитывая, что обычная степенная функция рассматривает эти дополнительные данные для отрицательных базисов или показателей как неопределенные? И как эти регионы или части сюжета называются в математике (это технический термин)?
Также открыт для любого другого подхода или алгоритма