File indexing completed on 2024-04-28 11:20:30
0001 /* 0002 SPDX-License-Identifier: GPL-2.0-or-later 0003 SPDX-FileCopyrightText: 2016 Ivan Lakhtanov <ivan.lakhtanov@gmail.com> 0004 */ 0005 #include "juliaextensions.h" 0006 0007 #include <QDebug> 0008 #include <KLocalizedString> 0009 0010 #include "settings.h" 0011 0012 #include "juliascriptloading.h" 0013 0014 #define JULIA_EXT_CDTOR(name) Julia##name##Extension::Julia##name##Extension(QObject *parent) : name##Extension(parent) {} \ 0015 Julia##name##Extension::~Julia##name##Extension() {} 0016 0017 0018 JULIA_EXT_CDTOR(LinearAlgebra) 0019 0020 QString JuliaLinearAlgebraExtension::createVector( 0021 const QStringList &entries, 0022 Cantor::LinearAlgebraExtension::VectorType type) 0023 { 0024 QString command; 0025 command += QLatin1String("["); 0026 0027 QString separator = QLatin1String(type == ColumnVector ? ", " : " "); 0028 0029 for (const QString &entry : entries) { 0030 command += entry + separator; 0031 } 0032 0033 command.chop(separator.size()); 0034 command += QLatin1String("]\n"); 0035 0036 return command; 0037 } 0038 0039 QString JuliaLinearAlgebraExtension::createMatrix( 0040 const Cantor::LinearAlgebraExtension::Matrix &matrix) 0041 { 0042 QString command; 0043 command += QLatin1String("["); 0044 0045 for (const QStringList row : matrix) { 0046 for (const QString entry : row) { 0047 command += entry; 0048 command += QLatin1String(" "); 0049 } 0050 command.chop(1); 0051 command += QLatin1String("; "); 0052 } 0053 0054 command.chop(2); 0055 command += QLatin1String("]"); 0056 0057 return command; 0058 } 0059 0060 QString JuliaLinearAlgebraExtension::eigenValues(const QString &matrix) 0061 { 0062 return QString::fromLatin1("eig(%1)[1]").arg(matrix); 0063 } 0064 0065 QString JuliaLinearAlgebraExtension::eigenVectors(const QString &matrix) 0066 { 0067 return QString::fromLatin1("eig(%1)[2]").arg(matrix); 0068 } 0069 0070 QString JuliaLinearAlgebraExtension::identityMatrix(int size) 0071 { 0072 return QString::fromLatin1("eye(%1)").arg(size); 0073 } 0074 0075 QString JuliaLinearAlgebraExtension::invertMatrix(const QString &matrix) 0076 { 0077 return QString::fromLatin1("inv(%1)").arg(matrix); 0078 } 0079 0080 QString JuliaLinearAlgebraExtension::nullMatrix(int rows, int columns) 0081 { 0082 return QString::fromLatin1("zeros(%1, %2)").arg(rows).arg(columns); 0083 } 0084 0085 QString JuliaLinearAlgebraExtension::nullVector( 0086 int size, 0087 Cantor::LinearAlgebraExtension::VectorType type) 0088 { 0089 switch (type) { 0090 case ColumnVector: 0091 return QString::fromLatin1("zeros(%1)").arg(size); 0092 case RowVector: 0093 return QString::fromLatin1("zeros(%1, %2)").arg(1).arg(size); 0094 default: 0095 return Cantor::LinearAlgebraExtension::nullVector(size, type); 0096 } 0097 } 0098 0099 QString JuliaLinearAlgebraExtension::rank(const QString &matrix) 0100 { 0101 return QString::fromLatin1("rank(%1)").arg(matrix); 0102 } 0103 0104 QString JuliaLinearAlgebraExtension::charPoly(const QString &matrix) 0105 { 0106 return QString::fromLatin1("poly(%1)").arg(matrix); 0107 } 0108 0109 0110 JULIA_EXT_CDTOR(Packaging) 0111 0112 QString JuliaPackagingExtension::importPackage(const QString &package) 0113 { 0114 return QString::fromLatin1("import %1").arg(package); 0115 } 0116 0117 0118 JULIA_EXT_CDTOR(Plot) 0119 0120 QString JuliaPlotExtension::plotFunction2d( 0121 const QString &function, 0122 const QString &variable, 0123 const QString &left, 0124 const QString &right) 0125 { 0126 QString command; 0127 QString limits; 0128 0129 switch(JuliaSettings::plotExtenstionGraphicPackage()) 0130 { 0131 case JuliaSettings::EnumPlotExtenstionGraphicPackage::gr: 0132 { 0133 if (!left.isEmpty() && !right.isEmpty()) 0134 limits = QString::fromLatin1("GR.xlim((%1, %2))\n").arg(left).arg(right); 0135 0136 command = QString::fromLatin1( 0137 "import GR\n" 0138 "\n" 0139 "%3" 0140 "GR.plot(%1, %2)" 0141 ).arg(variable).arg(function).arg(limits); 0142 break; 0143 } 0144 0145 case JuliaSettings::EnumPlotExtenstionGraphicPackage::plots: 0146 if (!left.isEmpty() && !right.isEmpty()) 0147 limits = QString::fromLatin1(", xlims = (%1, %2)").arg(left).arg(right); 0148 0149 command = QString::fromLatin1( 0150 "import Plots\n" 0151 "\n" 0152 "Plots.plot(%1, %2%3)" 0153 ).arg(variable, function, limits); 0154 break; 0155 0156 case JuliaSettings::EnumPlotExtenstionGraphicPackage::pyplot: 0157 if (!left.isEmpty() && !right.isEmpty()) 0158 limits = QString::fromLatin1("PyPlot.xlim(%1, %2)\n").arg(left).arg(right); 0159 0160 command = QString::fromLatin1( 0161 "import PyPlot\n" 0162 "\n" 0163 "%3" 0164 "PyPlot.plot(%1, %2)" 0165 ).arg(variable, function, limits); 0166 break; 0167 0168 case JuliaSettings::EnumPlotExtenstionGraphicPackage::gadfly: 0169 if (!left.isEmpty() && !right.isEmpty()) 0170 limits = QString::fromLatin1(", Gadfly.Scale.x_continuous(minvalue=%1, maxvalue=%2)").arg(left).arg(right); 0171 0172 command = QString::fromLatin1( 0173 "import Gadfly\n" 0174 "\n" 0175 "Gadfly.plot(x=%1, y=%2%3)" 0176 ).arg(variable, function, limits); 0177 break; 0178 } 0179 0180 return command; 0181 } 0182 0183 QString JuliaPlotExtension::plotFunction3d( 0184 const QString &function, 0185 const VariableParameter& var1, 0186 const VariableParameter& var2) 0187 { 0188 QString command; 0189 0190 const Interval& interval1 = var1.second; 0191 const Interval& interval2 = var2.second; 0192 0193 QString interval1Limits; 0194 QString interval2Limits; 0195 0196 switch(JuliaSettings::plotExtenstionGraphicPackage()) 0197 { 0198 case JuliaSettings::EnumPlotExtenstionGraphicPackage::gr: 0199 { 0200 if (!interval1.first.isEmpty() && !interval1.second.isEmpty()) 0201 interval1Limits = QString::fromLatin1("GR.xlim((%1, %2))\n").arg(interval1.first).arg(interval1.second); 0202 0203 if (!interval2.first.isEmpty() && !interval2.second.isEmpty()) 0204 interval1Limits = QString::fromLatin1("GR.ylim((%1, %2))\n").arg(interval2.first).arg(interval2.second); 0205 0206 command = QString::fromLatin1( 0207 "import GR\n" 0208 "\n" 0209 "%4%5" 0210 "GR.plot3(%1, %2, %3)" 0211 ).arg(interval1.first, interval2.first, function, interval1Limits, interval2Limits); 0212 break; 0213 } 0214 0215 case JuliaSettings::EnumPlotExtenstionGraphicPackage::plots: 0216 if (!interval1.first.isEmpty() && !interval1.second.isEmpty()) 0217 interval1Limits = QString::fromLatin1(", xlims = (%1, %2)").arg(interval1.first).arg(interval1.second); 0218 0219 if (!interval2.first.isEmpty() && !interval2.second.isEmpty()) 0220 interval1Limits = QString::fromLatin1(", ylims = (%1, %2)").arg(interval2.first).arg(interval2.second); 0221 0222 command = QString::fromLatin1( 0223 "import Plots\n" 0224 "\n" 0225 "%4%5" 0226 "GR.plot3d(%1, %2, %3)" 0227 ).arg(interval1.first, interval2.first, function, interval1Limits, interval2Limits); 0228 break; 0229 0230 case JuliaSettings::EnumPlotExtenstionGraphicPackage::pyplot: 0231 if (!interval1.first.isEmpty() && !interval1.second.isEmpty()) 0232 interval1Limits = QString::fromLatin1("GR.xlim((%1, %2))\n").arg(interval1.first).arg(interval1.second); 0233 0234 if (!interval2.first.isEmpty() && !interval2.second.isEmpty()) 0235 interval1Limits = QString::fromLatin1("GR.ylim((%1, %2))\n").arg(interval2.first).arg(interval2.second); 0236 0237 command = QString::fromLatin1( 0238 "import GR\n" 0239 "\n" 0240 "%4%5" 0241 "PyPlot.plot3D(%1, %2, %3)" 0242 ).arg(interval1.first, interval2.first, function, interval1Limits, interval2Limits); 0243 break; 0244 0245 case JuliaSettings::EnumPlotExtenstionGraphicPackage::gadfly: 0246 command = i18n("# Sorry, but Gadfly don't support 3d plots"); 0247 break; 0248 } 0249 0250 return command; 0251 } 0252 0253 0254 JULIA_EXT_CDTOR(Script) 0255 0256 QString JuliaScriptExtension::runExternalScript(const QString &path) 0257 { 0258 return QString::fromLatin1("include(\"%1\")").arg(path); 0259 } 0260 0261 QString JuliaScriptExtension::scriptFileFilter() 0262 { 0263 return i18n("Julia script file (*.jl)"); 0264 } 0265 0266 QString JuliaScriptExtension::highlightingMode() 0267 { 0268 return QLatin1String("julia"); 0269 } 0270 0271 0272 JULIA_EXT_CDTOR(VariableManagement) 0273 0274 const QString JuliaVariableManagementExtension::REMOVED_VARIABLE_MARKER = 0275 QLatin1String("__REM__"); 0276 0277 QString JuliaVariableManagementExtension::addVariable( 0278 const QString &name, 0279 const QString &value) 0280 { 0281 return setValue(name, value); 0282 } 0283 0284 QString JuliaVariableManagementExtension::setValue( 0285 const QString &name, 0286 const QString &value) 0287 { 0288 return QString::fromLatin1("%1 = %2").arg(name).arg(value); 0289 } 0290 0291 QString JuliaVariableManagementExtension::removeVariable(const QString &name) 0292 { 0293 // There is no way to completely delete object from scope: 0294 // https://docs.julialang.org/en/v1/manual/faq/#How-do-I-delete-an-object-in-memory?-1 0295 return QString::fromLatin1("%1 = \"%2\"") 0296 .arg(name).arg(REMOVED_VARIABLE_MARKER); 0297 } 0298 0299 QString JuliaVariableManagementExtension::clearVariables() 0300 { 0301 return loadScript(QLatin1String("variables_cleaner")) 0302 .arg(REMOVED_VARIABLE_MARKER); 0303 } 0304 0305 QString JuliaVariableManagementExtension::saveVariables(const QString &fileName) 0306 { 0307 return loadScript(QLatin1String("variables_saver")).arg(fileName); 0308 } 0309 0310 QString JuliaVariableManagementExtension::loadVariables(const QString &fileName) 0311 { 0312 return loadScript(QLatin1String("variables_loader")).arg(fileName); 0313 }