How to multiply a RealVector by a RealMatrix? - java

How can I multiply a given RealVector by a RealMatrix? I can't find any "multiply" method on both classes, only preMultiply but it seems not work:
// point to translate
final RealVector p = MatrixUtils.createRealVector(new double[] {
3, 4, 5, 1
});
// translation matrix (6, 7, 8)
final RealMatrix m = MatrixUtils.createRealMatrix(new double[][] {
{1, 0, 0, 6},
{0, 1, 0, 7},
{0, 0, 1, 8},
{0, 0, 0, 1}
});
// p2 = m x p
final RealVector p2 = m.preMultiply(p);
// prints {3; 4; 5; 87}
// expected {9; 11; 13; 1}
System.out.println(p2);
Please compare the actual result with the expected result.
Is there also a way for multiplying a Vector3D by a 4x4 RealMatrix where the w component is throw away? (I'm looking not for custom implementation but an already existing method in the library).

preMultiply does not give you m x p but p x m. This would be suitable for your question but not for your comment // p2 = m x p.
To get the result you want you have two options:
Use RealMatrix#operate(RealVector) which produces m x p:
RealVector mxp = m.operate(p);
System.out.println(mxp);
Transpose the matrix before pre-multiplying:
RealVector pxm_t = m.transpose().preMultiply(p);
System.out.println(pxm_t);
Result:
{9; 11; 13; 1}

Related

how to rotate a sub-matrix NxN by 90 degree clockwise in a bigger AxB matrix - in Java

everyone ! I'm trying to rotate sub-matrix NxN for 90 degree clockwise within a bigger AxB matrix. Most answers I found is only dealt with a whole matrix NxN. Below is the example.
Given a A x B matrix rotate a sub-matrix NxN for 90 degree clockwise.
Sample input given [3 x 4] matrix rotate sub-matrix [3 x 3] for 90 degree clockwise.
0 [1 2 3 ] 4
5 [6 7 8 ] 9
10 [11 12 13] 14
Expected output
0 [11 6 1] 4
5 [12 7 2] 9
10 [13 8 3] 14
Really appreciate if someone can help me out. Thanks !
Try this.
top and left are the coordinates of the upper left corner of the submatrix.
n is the size of the submatrix.
static int[][] rotate(int[][] a, int top, int left, int n) {
int height = a.length, width = a[0].length;
int[][] b = new int[height][];
for (int x = 0; x < height; ++x)
b[x] = Arrays.copyOf(a[x], width);
for (int x = top, xmax = top + n, ty = left + n - 1; x < xmax; ++x, --ty)
for (int y = left, ymax = left + n, tx = 0; y < ymax; ++y, ++tx)
b[tx][ty] = a[x][y];
return b;
}
And
int[][] a = {
{0, 1, 2, 3, 4},
{5, 6, 7, 8, 9},
{10, 11, 12, 13, 14},
};
int[][] b = rotate(a, 0, 1, 3);
for (int[] row : b)
System.out.println(Arrays.toString(row));
output:
[0, 11, 6, 1, 4]
[5, 12, 7, 2, 9]
[10, 13, 8, 3, 14]

Find connected rectangles from a HashSet using java

I have a HashSet filled with custom rectangle object("name",center_X,center_Y, width, height). i wrote a method to find if two rectangles are connected(touch/intersect). But i want to get all the rectangles that are a group. For example: if rectA is connected with rectB, RectC is connected with rectB but not rectA directly they all are connected because rectB is common.
I can find the shapes that have direct connection. But I want to get the group where shapes with secondary connection is also included. I'd assume recursion is useful in this case but can't solve it yet. Any solution/suggestion?
public static void canItbeGroup(HashSet<RECTANGLE> ipRectangles)
{
Deque<RECTANGLE> ipDeque = new ArrayDeque<>(ipRectangles);
for (RECTANGLE currRectangle : ipDeque)
{
Set<String> tempGrpMbrShapeID = new HashSet<>();
RECTANGLE tempRect = ipDeque.pop();
for (RECTANGLE r : ipDeque)
{
if (tempRect.areShapesFriend(r))
{
tempGrpMbrShapeID.add(r.shapeID);
tempGrpMbrShapeID.add(tempRect.shapeID);
}
}
if (tempGrpMbrShapeID.size() > 1)
{
System.out.println(tempGrpMbrShapeID);
}
}
}
public static void main(String[] args)
{
HashSet<RECTANGLE> rectHS = new HashSet<>();
RECTANGLE aRect = new RECTANGLE("a", 3, 2, 2, 2);
RECTANGLE aInnerRect = new RECTANGLE("aIn", 3, 2, 1, 1);
RECTANGLE bRect = new RECTANGLE("b", 5, 3, 2, 2);
RECTANGLE cRect = new RECTANGLE("c", 7, 3, 2, 2);
RECTANGLE dRect = new RECTANGLE("d", 4, 5, 4, 2);
RECTANGLE eRect = new RECTANGLE("e", 11, 3, 2, 2);
RECTANGLE fRect = new RECTANGLE("f", 11, 6, 2, 2);
RECTANGLE gRect = new RECTANGLE("g", 13, 3, 2, 2);
RECTANGLE hRect = new RECTANGLE("h", 4, 8, 2, 2);
RECTANGLE iRect = new RECTANGLE("i", 14, 1, 2, 2);
RECTANGLE jRect = new RECTANGLE("j", 16, 7, 2, 2);
RECTANGLE kRect = new RECTANGLE("k", 15, 6, 2, 2);
RECTANGLE lRect = new RECTANGLE("l", 8, 8, 2, 2);
RECTANGLE mRect = new RECTANGLE("m", 5, 10, 2, 2);
rectHS.add(aRect);
rectHS.add(bRect);
rectHS.add(cRect);
rectHS.add(eRect);
rectHS.add(dRect);
rectHS.add(fRect);
rectHS.add(gRect);
rectHS.add(aInnerRect);
rectHS.add(hRect);
rectHS.add(iRect);
rectHS.add(jRect);
rectHS.add(kRect);
rectHS.add(lRect);
rectDQ.add(aRect);
rectDQ.add(bRect);
rectDQ.add(cRect);
rectDQ.add(dRect);
rectDQ.add(eRect);
canItbeGroup(rectHS);
}
output i get:
[a, b, aIn],[b, c, d],[g, i],[e, g],[j, k],[c, d]
I'll need the group as
[a,b,aIn,c,d], [e,g,i], [j,k]
I won't solve the problem for you, but I will give you a general approach.
Generate an initial Collection<Set<String>>. This is effectively what you've already done, but you'll need to store them so that you can merge the sets, rather than printing the group as soon as your find them
Iterate over all groups (i), and compare each group to every other group (j)
If the i contains any item of j then merge the sets (put all items of j into i, and remove all items from j)
Go back to 2 and repeat until you perform 1 full iteration where no merges occur.
Iterate again and remove any empty sets.

Calculate average top third of the population

Could you guys help me which apache-commons-math classes can I use to calculate the average of the top third of the population.
To calculate the average I know can use org.apache.commons.math3.stat.descriptive.DescriptiveStatistics.
How to get the top third of the population?
Example
Population: 0, 0, 0, 0, 0, 1, 2, 2, 3, 5,14
Top third: 2, 3, 5, 14
Average = 24/4= 6.0
First of all what do you call top third of population?
If set is divides by 3 and remainder is 0, then its is simple, but in your case 11%3 = 2.
So You should know how to get top third when remainder is not equal 0.
I would suggest You to use Arrays procedures, to get Top third of set. If You still want to use DescriptiveStatistics you can invoke it.
double[] set = {0, 0, 0, 0, 0, 1, 2, 2, 3,4,5};
Arrays.sort(set);
int from = 0;
if (set.length % 3==0){
from = set.length/3*2 ;
}
if (set.length % 3 != 0){
from = Math.round(set.length/3*2) + 1;
}
double [] topThirdSet = Arrays.copyOfRange(set,from , set.length);
DescriptiveStatistics ds = new DescriptiveStatistics(topThirdSet);
System.out.println(ds.getMean());

how to determine a correct domain for a range of numbers for drawing a line-graph?

I want to create a line graph but the range of numbers are different sometimes its like :
1,2,5,8,10
and sometimes its like :
-5 , -1 , 4 , 5, 15 , 8 ,20 ,...
by studying excel and openoffice I understand that they can indicate a range something like :
minNumber - k to maxNumber + k
and they divide the Y axis into equal area.
is there any specific formula for doing these things ?
When I looked at this problem I found that commercial products do a nice job of extending the range just enough to achieve pleasingly nice round numbers for their tick marks. If this is something you are interested in, take a look at this C# code that I wrote to try out different algorithms:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TickPicker
{
class TickPicker
{
double tickLow;
double tickHigh;
double tickUnit;
double tickCount;
//static double[] targetUnits = { 1, 2, 5, 10 };
static double[] targetUnits = { 1, 2, 2.5, 5, 10 };
static int[] roundFactors = { 1, 5, 4, 2, 1 };
//static double[] targetUnits = { 1, 1.5, 2.5, 5, 10 };
//static double[] targetUnits = { 1, 1.25, 2, 2.5, 5, 10 };
//static double[] targetUnits = { 1, 1.25, 1.5, 2, 2.5, 5, 10 };
//static double[] targetUnits = { 1, 1.25, 2, 5, 10 };
//static double[] targetUnits = { 1, 1.25, 1.5, 2, 5, 10 };
static double[] targetLogs = arrayLog(targetUnits);
TickPicker(double low, double high, int tickCountGoal)
{
double range = high - low;
double divGoal = range / (tickCountGoal - 2);
double logGoal = Math.Log10(divGoal);
double powerFactor = Math.Floor(logGoal);
logGoal = logGoal - powerFactor;
int closestIndex = findClosest(targetLogs, logGoal);
tickUnit = targetUnits[closestIndex] * (Math.Pow(10, powerFactor));
// Ensure the actual range encompasses the intended range
// The roundFactor discourages the .5 on the low and high range
int roundFactor = roundFactors[closestIndex];
tickLow = Math.Floor(low / tickUnit / roundFactor) * tickUnit * roundFactor;
tickHigh = Math.Ceiling(high / tickUnit / roundFactor) * tickUnit * roundFactor;
tickCount = (tickHigh - tickLow) / tickUnit;
}
static double[] arrayLog(double[] inputs)
{
double[] retVal = new double[inputs.Length];
int x = 0;
foreach (double input in inputs)
{
retVal[x] = Math.Log10(inputs[x]);
x++;
}
return retVal;
}
static int findClosest(double[] candidates, double input)
{
int low = 0;
for(int i = 1; i < candidates.Length && input > candidates[i]; i++)
{
low = i;
}
int high = low + 1;
return candidates[high] - input < input - candidates[low] ? high : low;
}
static void testPicker(double low, double high, int tickCountGoal)
{
TickPicker picker = new TickPicker(low, high, tickCountGoal);
System.Console.WriteLine("[{0}:{1}]/{2} gives [{3}:{4}] with {5} ticks of {6} units each.", low, high, tickCountGoal, picker.tickLow, picker.tickHigh, picker.tickCount, picker.tickUnit);
}
static void Main(string[] args)
{
testPicker(4.7, 39.2, 13);
testPicker(4.7, 39.2, 16);
testPicker(4.7, 39.2, 19);
testPicker(4.7, 39.2, 21);
testPicker(4.7, 39.2, 24);
testPicker(1967, 2011, 20);
testPicker(1967, 2011, 10);
testPicker(2.71, 3.14, 5);
testPicker(.0568, 13, 20);
}
}
}
I think you mean minNumber and not meanNumber.
The formula is close to what you say. Your range is maxNumber - minNumber. If you want some space on either side add 2k, where k is the space for either side. You know your graph is Y pixels wide. Y/range is how many pixels there are per unit for your graph.
You basically apply this adjustment while drawing the graph. Apply a shift based on your min, and then a strech based on your pixel/unit.
So Drawing point X means you are actually drawing at ((X - min) / pixels per unit).
I'm not 100% convinced that this is a programming question (although there are a decent handful of graphing libraries one could use), but the general idea would be this.
You have these points coming in, let's say -5. That's the 0th value we've received, so for an x value of 0, we place -5 on the y-axis. We repeat for -1, 4, etc.
So, you'd get a list looking something like this (figuratively):
X | Y
0 | -5
1 | -1
2 | 4
3 | 5
4 | 15
The result is a scatterplot (not a line), but there are tools in Excel to get that for you.
[EDIT] To get it as an actual function, you could use the following form:
y-y_1=m(x-x_1)
Where m = (y_2-y_1)/(x_2-x_1), y_2 is your highest y-value, y_1 is your lowest, x_2 is your highest x-value, and x_1 is your lowest.

Eclipse reporting errors on arrays for Android

I'm trying to get a 3D array initialized for a game I'm working on, after multiple syntax changes I couldn't figure out how to get it to work! What I started with was:
public class AnimationView extends SurfaceView implements SurfaceHolder.Callback {//Create bitmaps.
Bitmap bitmapGoal = BitmapFactory.decodeResource(this.getResources(), R.drawable.goal);
Bitmap bitmapOrig = BitmapFactory.decodeResource(this.getResources(), R.drawable.ball);
Bitmap bitmap = Bitmap.createScaledBitmap(bitmapOrig, 150, 150, true);
//initialize the canvas.
private Canvas c;
private int score[] = {0, 0, 0, 0};
public int numBalls = 1;
//we support up to 4 balls. thus each array is 4 bit.
private int ballX[] = {0, 200, 400, 600};
private double ballY[] = {0, 0, 0, 0};
private double dirV[] = {0, 0, 0, 0};
private int dirH[] = {30, 30, 30, 30};
private static final int SCALE = 10;
private double elasticity = .6;
private int rotationNow[] = {5, 5, 5, 5};
private int rotationDraw[] = {0, 0, 0, 0};
class AnimationThread extends Thread {
//Are we running currently?
private boolean mRun;
//layer 1 is how many balls, 4 layers deep.
//layer 2 is which ball we're talking about, either 1, 2, 3, or 4 layers deep, depending on layer 1.
//layer 3 is the bounds of the ball, dependent on how many there are total.
//layer 3 is formatted x-min, x-max, y-min, y-max
int[][][] bounds = new int[][][] {
{ {0, c.getWidth() - bitmap.getWidth(), 0, c.getHeight() - bitmap.getHeight()}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0} },
//end first layer
{ {0, c.getWidth() / 2 - bitmap.getWidth(), 0, c.getHeight() - bitmap.getHeight()}, {c.getWidth() / 2, c.getWidth() - bitmap.getWidth(), 0, c.getHeight() - bitmap.getHeight()}, {0, 0, 0, 0}, {0, 0, 0, 0} },
//end second layer
{ {0, c.getWidth() / 3 - bitmap.getWidth(), 0, c.getHeight() - bitmap.getHeight()}, {c.getWidth() / 3, c.getWidth() * 2 / 3 - bitmap.getWidth(), 0, c.getHeight() - bitmap.getHeight()}, {c.getWidth() * 2 / 3, c.getWidth() - bitmap.getWidth(), 0, c.getHeight() - bitmap.getHeight()}, {0, 0, 0, 0} },
//end third layer
{ {0, c.getWidth() / 2, 0, c.getHeight() / 2}, {c.getWidth() / 2, c.getWidth(), 0, c.getHeight() / 2}, {0, c.getWidth() / 2, c.getHeight() / 2, c.getHeight()}, {c.getWidth() / 2, c.getWidth(), c.getHeight() / 2, c.getHeight()} }
//end fourth, and final layer!
};
Sorry about the weird formatting error. I know this doesn't help anything. There is a new line between ymax and int[][][].
You don't exactly need to look through it and understand, but this compiled and then errored out during execution. So then I tried to make a simple 3D array, I started with:
int[][][] bounds = new int[1][1][1];
bounds[0][0][0] = 0;
Eclipse had it's red squiggly under the semi-colon on the first line. Saying
'Syntax error on token ";", { expected after this token'
This is where it gets frustrating. Because that exact same code copy/pasted into a regular Java program works fine, but I can NOT get it to work inside an Android project. I then simplified some stuff, to this:
int[] bounds = new int[1];
bounds[0] = 0;
Exact same error, exact same place! Why Eclipse?? I also tried it with "int bounds[][][]" as opposed to "int[][][] bounds" but no difference, still same error.
I've rebooted my computer, cleaned my project multiple times, restarted Eclipse. I'm out of ideas. Do you have any??
Well, seems like the problem is not before, but after the code you pasted.
this assignment - bounds[0][0][0] = 0; is probably not in any method and this is illegal. When Eclipse sees an expression that need to be inside a method, it expects the line above to be the method declaration, so it expects '{' as a beginning of a method block, and not ';'
Ok, I feel ridiculous. After being very, very confused at why the variable couldn't initialize and why the very simple code then wouldn't compile. It turns out, though the canvas and bitmaps were available, it was infact them returning null values into the array.
So I got it working now.
Also, for my first question here, I was extremely impressed with the speediness of the solutions. Thanks a ton!
int[][][] bounds = new int[1][1][1];
bounds[0][0][0] = 0;
I copied these two lines and seem to be compiling fine.
I think you might have forgot to comment the earlier declaration of bounds . (or) you might be missing braces or something like that

Categories

Resources