File indexing completed on 2024-04-14 03:40:48

0001 /*
0002     KmPlot - a math. function plotter for the KDE-Desktop
0003 
0004     SPDX-FileCopyrightText: 2006 David Saxton <david@bluehaze.org>
0005 
0006     This file is part of the KDE Project.
0007     KmPlot is part of the KDE-EDU Project.
0008 
0009     SPDX-License-Identifier: GPL-2.0-or-later
0010 
0011 */
0012 
0013 #include "vector.h"
0014 #include "function.h"
0015 
0016 #include <assert.h>
0017 #include <string.h>
0018 
0019 // BEGIN class Vector
0020 Vector Vector::operator+(const Vector &other) const
0021 {
0022     Vector v(*this);
0023     v += other;
0024     return v;
0025 }
0026 
0027 Vector &Vector::operator+=(const Vector &other)
0028 {
0029     assert(size() == other.size());
0030     for (int i = 0; i < size(); ++i)
0031         (*this)[i] += other[i];
0032 
0033     return *this;
0034 }
0035 
0036 Vector Vector::operator-(const Vector &other) const
0037 {
0038     Vector v(*this);
0039     v -= other;
0040     return v;
0041 }
0042 
0043 Vector &Vector::operator-=(const Vector &other)
0044 {
0045     assert(size() == other.size());
0046     for (int i = 0; i < size(); ++i)
0047         (*this)[i] -= other[i];
0048 
0049     return *this;
0050 }
0051 
0052 Vector Vector::operator*(double x) const
0053 {
0054     Vector v(*this);
0055     v *= x;
0056     return v;
0057 }
0058 
0059 Vector &Vector::operator*=(double x)
0060 {
0061     for (int i = 0; i < size(); ++i)
0062         (*this)[i] *= x;
0063     return *this;
0064 }
0065 
0066 Vector &Vector::operator=(const Vector &other)
0067 {
0068     // I don't much like Qt's copy-on-write behaviour.
0069     // At least in KmPlot, it makes a small number of cases marginally faster,
0070     // and a lot of cases a lot slower. This is because allocating and freeing
0071     // memory is a lot slower than copying memory.
0072     //
0073     // In fact, it can make drawing differential equations several times slower.
0074 
0075     resize(other.size());
0076     memcpy(m_data.data(), other.m_data.data(), size() * sizeof(double));
0077 
0078     return *this;
0079 }
0080 
0081 Vector &Vector::operator=(const QVector<Value> &other)
0082 {
0083     int size = other.size();
0084     resize(size);
0085     for (int i = 0; i < size; ++i)
0086         (*this)[i] = other[i].value();
0087     return *this;
0088 }
0089 
0090 void Vector::combine(const Vector &a, double k, const Vector &b)
0091 {
0092     assert(a.size() == b.size());
0093     int n = a.size();
0094     resize(n);
0095 
0096     double *d1 = m_data.data();
0097     const double *d2 = a.m_data.data();
0098     const double *d3 = b.m_data.data();
0099 
0100     for (int i = 0; i < n; ++i)
0101         d1[i] = d2[i] + k * d3[i];
0102 }
0103 
0104 void Vector::addRK4(double dx, const Vector &k1, const Vector &k2, const Vector &k3, const Vector &k4)
0105 {
0106     double *d = m_data.data();
0107     const double *d1 = k1.m_data.data();
0108     const double *d2 = k2.m_data.data();
0109     const double *d3 = k3.m_data.data();
0110     const double *d4 = k4.m_data.data();
0111 
0112     int n = size();
0113 
0114     for (int i = 0; i < n; ++i)
0115         d[i] += (dx / 6) * (d1[i] + 2 * d2[i] + 2 * d3[i] + d4[i]);
0116 }
0117 // END class Vector