Is there any technique or package that calculates Root Mean Square(RMS) in Flutter?
I searched many blogs and packages but didn't find useful resource related to RMS implementation in Dart
This is the steps of Root Mean Square according to the link in the below:
Step 1: Get the squares of all the values
Step 2: Calculate the average of the obtained squares
Step 3: Finally, take the square root of the average
and this is the Dart implementation :
import 'dart:math';
void main() {
List<int> values = [1,3,5,7,9];
num result = 0;
num rootMeanSquare = 0;
for( var i = 0 ; i < values.length; i++ ) {
result = result + (values[i] * values[i]);
}
rootMeanSquare = sqrt(result / values.length);
print(rootMeanSquare);
}
https://byjus.com/maths/root-mean-square/#:~:text=Root%20Mean%20Square%20Formula&text=For%20a%20group%20of%20n,x%20n%202%20%20N
Related
Question: How can I efficiently compute the minimum distance between two axis-aligned boxes in n-dimensions?
Box format: The boxes, A and B, are given by their minimum and maximum points, A_min, A_max, B_min, B_max, each of which is a n-dimensional vector. That is, the boxes may be written mathematically as the following cartesian products of intervals:
A = [A_min(1), A_max(1)] x [A_min(2), A_max(2)] x ... x [A_min(n), A_max(n)]
B = [B_min(1), B_max(1)] x [B_min(2), B_max(2)] x ... x [B_min(n), B_max(n)]
Picture: here is a picture demonstrating the idea in 2D:
Note: Note: I ask this question, and answer it myself, because this question (in general n-dimensional form) appears to be absent from stackoverflow even after all these years. Good answers to this question are hard to find on the internet more generally. After googling around, I eventually had to figure this out myself, and am posting here to spare future people the same trouble.
The minimum distance between the boxes is given by:
dist = sqrt(||u||^2 + ||v||^2)
where
u = max(0, A_min - B_max)
v = max(0, B_min - A_max)
The maximization is done entrywise on the vectors (i.e., max(0, w) means replace all negative entries of vector w with zero, but leave the positive entries unchanged). The notation ||w|| means the euclidean norm of the vector w (square root of the sum of the squares of the entries).
This does not require any case-by-case analysis, and works for any dimension regardless of where the boxes are with respect to each other.
python code:
import numpy as np
def boxes_distance(A_min, A_max, B_min, B_max):
delta1 = A_min - B_max
delta2 = B_min - A_max
u = np.max(np.array([np.zeros(len(delta1)), delta1]), axis=0)
v = np.max(np.array([np.zeros(len(delta2)), delta2]), axis=0)
dist = np.linalg.norm(np.concatenate([u, v]))
return dist
type Rect = { x: number; y: number; length: number; width: number };
export function boxesDistance(a: Rect, b: Rect) {
const deltas = [a.x - b.x - b.width, a.y - b.y - b.length, b.x - a.x - a.width, b.y - a.y - a.length];
const sum = deltas.reduce((total, d) => {
return d > 0 ? total + d ** 2 : total;
}, 0);
return Math.sqrt(sum);
}
This is the equivalent code in typescript without the use of any libraries, though the input parameters were slightly different in my case.
The distance between two axis-aligned bounding boxes (AABB) can be computed as follows:
Find the intersection box of two input boxes, which can be expressed in C++:
Box Box::intersection( const Box & b ) const
{
Box res;
for ( int i = 0; i < V::elements; ++i )
{
res.min[i] = std::max( min[i], b.min[i] );
res.max[i] = std::min( max[i], b.max[i] );
}
return res;
}
where min and max are two corner points of a box. The "intersection" will be inverted (res.min[i] > res.max[i]) if two input boxes do not intersect actually.
Then the squared distance between two boxes is:
T Box::getDistanceSq( const Box & b ) const
{
auto ibox = intersection( b );
T distSq = 0;
for ( int i = 0; i < V::elements; ++i )
if ( ibox.min[i] > ibox.max[i] )
distSq += sqr( ibox.min[i] - ibox.max[i] );
return distSq;
}
The function returns zero if input boxes touch or intersect.
The code above was taken from MeshLib and it works for arbitrary n-dimensions cases (V::elements=n).
I'm trying to use the zoomCallback function to set up interaction between my dygrpahs chart and a map chart. My x values are timestamps in seconds but since the sample rate is about 100Hz the timestamps are stored as float numbers.
The goal is that when dygraphs chart is zoomed in, the new x1 and x2 will be used to extract a piece of GPS track (lat, lng points). The extracted track will be used to re-fit the map boundaries - this will look like a "zoom in" on the map chart.
In my dygraphs options I specified the callback:
zoomCallback: function(x1,x2) {
let x1Index = graphHolder.getRowForX(x1);
let x2Index = graphHolder.getRowForX(x2);
// further code
}
But it looks like the zoom is not "snapped" to existing timestamp points so both x1Index and x2Index are null. Only when I zoom out, they'll correctly point to row 0 and the last row of data.
So the question is - is there a way to make the zoom snap only to the nearest existing x value so the row number can be returned? Or, is there an alternative to do what I want?
Thanks for any insights!
You can access the x-axis values via g.getValue(row, 0). From this you can either do a linear scan to find the first row in the range or (fancier but faster) use a binary search.
Here's a way to do the linear scan:
const [x1, x2] = g.xAxisRange();
let letRow = null, highRow = null;
for (let i = 0; i < g.numRows(); i++) {
if (g.getValue(i, 0) >= x1) {
lowRow = i;
break;
}
}
for (let i = g.numRows() - 1; i >= 0; i--) {
if (g.getValue(i, 0) <= x2) {
highRow = i;
break;
}
}
const dataX1 = g.getValue(lowRow, 0);
const dataX2 = g.getValue(highRow, 0);
For larger data sets you might want to do a binary search using something like lodash's _.sortedIndex.
Update Here's a binary search implementation. No promises about the exact behavior on the boundaries (i.e. whether it always returns indices that are inside the visible range or indices which contain the visible range).
function dygraphBinarySearch(g, x) {
let low = 0;
let high = g.numRows() - 1;
while (high > low) {
let i = Math.floor(low + (high - low) / 2);
const xi = g.getValue(i, 0);
if (xi < x) {
low = i + 1;
} else if (xi > x) {
high = i - 1;
} else {
return i;
}
}
return low;
}
function getVisibleDataRange(g) {
const [x1, x2] = g.xAxisRange();
let lowI = dygraphBinarySearch(g, x1);
let highI = dygraphBinarySearch(g, x2);
return [lowI, highI];
}
I am trying to implement an inverse FFT in a HLSL compute shader and don't understand how the new inversebits function works. The shader is run under Unity3D, but that shouldn't make a difference.
The problem is, that the resulting texture remains black with the exception of the leftmost one or two pixels in every row. It seems to me, as if the reversebits function wouldn't return the correct indexes.
My very simple code is as following:
#pragma kernel BitReverseHorizontal
Texture2D<float4> inTex;
RWTexture2D<float4> outTex;
uint2 getTextureThreadPosition(uint3 groupID, uint3 threadID) {
uint2 pos;
pos.x = (groupID.x * 16) + threadID.x;
pos.y = (groupID.y * 16) + threadID.y;
return pos;
}
[numthreads(16,16,1)]
void BitReverseHorizontal (uint3 threadID : SV_GroupThreadID, uint3 groupID : SV_GroupID)
{
uint2 pos = getTextureThreadPosition(groupID, threadID);
uint xPos = reversebits(pos.x);
uint2 revPos = uint2(xPos, pos.y);
float4 values;
values.x = inTex[pos].x;
values.y = inTex[pos].y;
values.z = inTex[revPos].z;
values.w = 0.0f;
outTex[revPos] = values;
}
I played around with this for quite a while and found out, that if I replace the reversebits line with this one here:
uint xPos = reversebits(pos.x << 23);
it works. Although I have no idea why. Could be just coincidence. Could someone please explain to me, how I have to use the reversebits function correctly?
Are you sure you want to reverse the bits?
x = 0: reversed: x = 0
x = 1: reversed: x = 2,147,483,648
x = 2: reversed: x = 1,073,741,824
etc....
If you fetch texels from a texture using coordinates exceeding the width of the texture then you're going to get black. Unless the texture is > 1 billion texels wide (it isn't) then you're fetching well outside the border.
I am doing the same and came to the same problem and these answers actually answered it for me but i'll give you the explanation and a whole solution.
So the solution with variable length buffers in HLSL is:
uint reversedIndx;
uint bits = 32 - log2(xLen); // sizeof(uint) - log2(numberOfIndices);
for (uint j = 0; j < xLen; j ++)
reversedIndx = reversebits(j << bits);
And what you found/noticed essentially pushes out all the leading 0 of your index so you are just reversing the least significant or rightmost bits up until the max bits we want.
for example:
int length = 8;
int bits = 32 - 3; // because 1 << 3 is 0b1000 and we want the inverse like a mask
int j = 6;
and since the size of an int is generally 32bits in binary j would be
j = 0b00000000000000000000000000000110;
and reversed it would be (AKA reversebits(j);)
j = 0b01100000000000000000000000000000;
Which was our error, so j bit shifted by bits would be
j = 0b11000000000000000000000000000000;
and then reversed and what we want would be
j = 0b00000000000000000000000000000011;
The only descriptions I can find about "adjusted complete" linkage say something like: "same as complete linkage, but with largest within cluster distance"
What is meant by "within cluster distance"?
How is the distance between two clusters finally calculated using this linkage approach?
Thanks for your replies!
One of the great things about open-source software is that you can find out exactly how the software works. The code below shows Weka's source code of the HierarchicalClusterer algorithm, more specifically it shows the part which implements the COMPLETE and ADJCOMPLETE functionality. The difference is as follows:
Just like the COMPLETE linkage method, compute the maximum distance between one node from cluster 1 and one node from cluster 2 and store this in fBestDist
Then, find the largest distance between nodes within cluster 1 or cluster 2 and store this in fMaxDist
Finally subtract fMaxDist from fBestDist
So the distance between two clusters calculated using ADJCOMPLETE as linkType corresponds to the COMPLETE distance minus the largest distance between 2 nodes within either cluster 1 or cluster 2.
Adjusted Complete-Link was proposed in the following paper:
Sepandar Kamvar, Dan Klein and Christopher Manning (2002). Interpreting and Extending Classical Agglomerative Clustering Algorithms Using a Model-Based Approach. In Proceedings of 19th International Conference on Machine Learning (ICML-2002)
According to it (section 4.2), Adjusted Complete-Link is a version of Complete-Link which should be used if the clusters having varying radii (see Figure 10).
case COMPLETE:
case ADJCOMLPETE:
// find complete link distance aka maximum link, which is the largest distance between
// any item in cluster1 and any item in cluster2
fBestDist = 0;
for (int i = 0; i < cluster1.size(); i++) {
int i1 = cluster1.elementAt(i);
for (int j = 0; j < cluster2.size(); j++) {
int i2 = cluster2.elementAt(j);
double fDist = fDistance[i1][i2];
if (fBestDist < fDist) {
fBestDist = fDist;
}
}
}
if (m_nLinkType == COMPLETE) {
break;
}
// calculate adjustment, which is the largest within cluster distance
double fMaxDist = 0;
for (int i = 0; i < cluster1.size(); i++) {
int i1 = cluster1.elementAt(i);
for (int j = i+1; j < cluster1.size(); j++) {
int i2 = cluster1.elementAt(j);
double fDist = fDistance[i1][i2];
if (fMaxDist < fDist) {
fMaxDist = fDist;
}
}
}
for (int i = 0; i < cluster2.size(); i++) {
int i1 = cluster2.elementAt(i);
for (int j = i+1; j < cluster2.size(); j++) {
int i2 = cluster2.elementAt(j);
double fDist = fDistance[i1][i2];
if (fMaxDist < fDist) {
fMaxDist = fDist;
}
}
}
fBestDist -= fMaxDist;
break;
Sounds like I got the concept but cant seems to get the implementation correct. eI have a cluster (an ArrayList) with multiple points, and I want to calculate avg distance. Ex: Points in cluster (A, B, C, D, E, F, ... , n), Distance A-B, Distance A-C, Distance A-D, ... Distance A,N, Distance (B,C) Distance (B,D)... Distance (B,N)...
Thanks in advance.
You don't want to double count any segment, so your algorithm should be a double for loop. The outer loop goes from A to M (you don't need to check N, because there'll be nothing left for it to connect to), each time looping from curPoint to N, calculating each distance. You add all the distances, and divide by the number of points (n-1)^2/2. Should be pretty simple.
There aren't any standard algorithms for improving on this that I'm aware of, and this isn't a widely studied problem. I'd guess that you could get a pretty reasonable estimate (if an estimate is useful) by sampling distances from each point to a handful of others. But that's a guess.
(After seeing your code example) Here's another try:
public double avgDistanceInCluster() {
double totDistance = 0.0;
for (int i = 0; i < bigCluster.length - 1; i++) {
for (int j = i+1; j < bigCluster.length; j++) {
totDistance += distance(bigCluster[i], bigCluster[j]);
}
}
return totDistance / (bigCluster.length * (bigCluster.length - 1)) / 2;
}
Notice that the limit for the first loop is different.
Distance between two points is probably sqrt((x1 - x2)^2 + (y1 -y2)^2).
THanks for all the help, Sometimes after explaining the question on forum answer just popup to your mind. This is what I end up doing.
I have a cluster of point, and I need to calculate the avg distance of points (pairs) in the cluster. So, this is what I did. I am sure someone will come with a better answer if so please drop a note. Thanks in advance.
/**
* Calculate avg distance between points in cluster
* #return
*/
public double avgDistanceInCluster() {
double avgDistance = 0.0;
Stack<Double> holder = new Stack<Double>();
for (int i = 0; i < cluster.size(); i++) {
System.out.println(cluster.get(i));
for (int j = i+1; j < cluster.size(); j++) {
avgDistance = (cluster.get(i) + cluster.get(j))/2;
holder.push(avgDistance);
}
}
Iterator<Double> iter = holder.iterator();
double avgClusterDist = 0;
while (iter.hasNext()) {
avgClusterDist =+ holder.pop();
System.out.println(avgClusterDist);
}
return avgClusterDist/cluster.size();
}