I am trying to implement the class Vector as an abstract one and have stuff like Vector2D and vector3D inherit from it. However, I ran into a problem with the overriding of operators, because they demand a static object reference be returned and I can't create one since I'm not allowed to call the abstract class' constructor there.
Here's the override I came up with:
public static Vector operator +(Vector v1, Vector v2)
{
if (v1.Dimension != v2.Dimension)
{
throw new Exception("Vector Dimensions Must Be Equal");
}
else
{
double[] newMatrix = new double[v1.Dimension]; //the matrix for the new (resulting) vector
for (int i = 0; i < v1.Dimension; i++)
{
newMatrix[i] = v1.Matrix[i] + v2.Matrix[i];
}
return new Vector(newMatrix);
//the abstract class has a constructor that takes a matrix
//and constructs a vector based on it, but it can't be called here
}
}
I tried both using the matrix constructor and generating a new empty instance (I have either of those constructors). Both boil down to the "can't instantiate abstract class" error.
I am aware that I could implement the operations in each of the classes that will derive from Vector, but I hoped there is some workaround/technique/design pattern which solves the problem in a more elegant way, but I don't seem to find any article out there talking about overriding operators in abstract classes (maybe that approach makes no sense..?). Anyway, any help is highly appreciated. Here is the whole class, if needed:
using System;
using System.Text;
namespace PhysicsProblems
{
public abstract class Vector
{
private static int IdCounter;
protected readonly int ID;
protected double[] Matrix;
protected int Dimension
{
get
{
return Matrix.Length;
}
}
public double Magnitude
{
get
{
double sum = 0;
foreach (var value in Matrix)
{
sum += value * value;
}
return Math.Sqrt(sum);
}
}
public Vector(int dimension)
{
ID = IdCounter++;
for (int i = 0; i < dimesion; i++)
{
Matrix[i] = 0;
}
}
public Vector(double[] matrix)
{
ID = IdCounter++;
matrix.CopyTo(Matrix, 0);
}
public static Vector operator +(Vector v1)
{
return v1;//to fix
}
public static Vector operator -(Vector v1)
{
for (int i = 0; i < v1.Matrix.Length; i++)
{
v1.Matrix[i] = -v1.Matrix[i];
}
return v1;//to fix
}
public static Vector operator +(Vector v1, Vector v2)
{
if (v1.Dimension != v2.Dimension)
{
throw new Exception("Vector Dimensions Must Be Equal");
}
else
{
double[] newMatrix = new double[v1.Dimension]; //the matrix for the new (resulting) vector
for (int i = 0; i < v1.Dimension; i++)
{
newMatrix[i] = v1.Matrix[i] + v2.Matrix[i];
}
return new Vector(newMatrix);
//the abstract class has a constructor that takes a matrix
//and constructs a vector based on it, but it can't be called here
}
}
public bool Equals(Vector vector)
{
if (vector.Dimension != Dimension) return false;
bool check = true;
for (int i = 0; i < Matrix.Length; i++)
{
if (vector.Matrix[i] != Matrix[i]) check = false;
}
return check;
}
public override bool Equals(object obj)
{
return Equals(obj as Vector);
}
public override int GetHashCode()
{
unchecked
{
int hash = 19;
hash = (hash * 486187739) + ID.GetHashCode();
hash = (hash * 486187739) + Dimension.GetHashCode();
return hash;
}
}
public override string ToString()
{
if (Dimension < 4)
{
var stringBuilder = new StringBuilder();
for (int i = 0; i < Dimension; i++)
{
stringBuilder
.Append(Constants.AxisLetters[i])
.Append(": ")
.Append(Matrix[i]);
if (i != Dimension - 1) stringBuilder.Append(", ");
}
return stringBuilder.ToString();
}
else
{
throw new NotImplementedException();
}
}
}
}
And the inheriting class Vector2D:
using System;
using System.Text;
namespace PhysicsProblems
{
public class Vector2D : Vector
{
public double X
{
get { return Matrix[0]; }
set { Matrix[0] = value; }
}
public double Y
{
get { return Matrix[1]; }
set { Matrix[1] = value; }
}
public Vector2D(int dimension) : base(dimension)
{ }
public Vector2D(double[] matrix) : base(matrix)
{ }
}
}
A little disclaimer I consider important: I'm fairly OK with OOP and have some experience, however, I took up C# a week or two ago. Therefore, rookie mistakes are to be expected
Related
I created the pair class and array class, but I'm lost on how to implement the quicksort algorithm.
I want to do it if ints are same then I should sort by double. I was able to implement quicksort with one value per index of array, but with this I just can't find any resources.
Maybe you guys have some resources or maybe you had the same problem?
By the way I'm trying to implement it with c#.
This is my pair class:
class Pair
{
public int integer = 0;
public double doubl = 0.0;
public Pair(int integer, double doubl)
{
this.integer = integer;
this.doubl = doubl;
}
public Pair()
{
}
public int Integer() { return integer; }
public double Doubl() { return doubl; }
}
And my data array class
class MyDataArray : DataArray
{
Pair[] data;
int operations = 0;
public MyDataArray(int n, int seed)
{
data = new Pair[n];
Random rand = new Random(seed);
for (int i = 0; i < n; i++)
{
data[i] = new Pair(rand.Next(1,100), rand.NextDouble());
}
}
public override int integer(int index)
{
return data[index].integer;
}
public override double doubl(int index)
{
return data[index].doubl;
}
public override void Swap(int i, int j)
{
Pair temp = data[i]; // c3 1
data[i] = data[j]; // c3 1
data[j] = temp; // c3 1
}
Your Pair class could implement IComparable<T>, and your quick sort algorithm could be implemented using the CompareTo method.
The IComparable<T> interface:
Defines a generalized comparison method that a value type or class implements to create a type-specific comparison method for ordering or sorting its instances.
You can see the documentation on the CompareTo method to see what the return values mean.
public class Pair : IComparable<Pair>
{
public int integer = 0;
public double doubl = 0.0;
public Pair(int integer, double doubl)
{
this.integer = integer;
this.doubl = doubl;
}
public Pair()
{
}
public int CompareTo(Pair other)
{
if (other == null)
{
return 1;
}
int result = integer.CompareTo(other.integer);
if (result == 0)
{
result = doubl.CompareTo(other.doubl);
}
return result;
}
public int Integer() { return integer; }
public double Doubl() { return doubl; }
}
If you prefer to use the comparison operators, you can implement them in terms of the CompareTo method. The documentation I liked has examples on how to do that.
//sort for integer
var SortedIntegerList = data.OrderBy(x=>x.integer);
//sort for double
var SortedDoubleList = data.OrderBy(x=>x.doubl);
OrderBy for objects uses Quicksort - What Sorting Algorithm Is Used By LINQ "OrderBy"? - so you can use that.
To avoid creating IComparer<Pair> interface you can construct it using Comparer<T>.Create from just comparison delegate:
var sorted = source.OrderBy(x => x, Comparer<Pair>.Create(
(p1, p2) => p1.Integer() - p2.Integer() != 0 ?
p1.Integer() - p2.Integer() :
Math.Sign(p1.Doubl() - p2.Doubl()))).ToList();
I want to implement my own Priority Queue in C# using the naive approach. I need to use PQ for edges in a graph to implement Prims algorithm. Here is what I've done so far:
public class Edge
{
private int v; // one vertex
private int w; // the other vertex
private int weight; // edge weight
public Edge(int v0, int w0, int weight0)
{
v = v0;
w = w0;
weight = weight0;
}
public Edge()
{
v = 0;
w = 0;
weight = 0;
}
public int get_weight()
{
return weight;
}
public int either()
{
return v;
}
public int the_other(int vertex)
{
if (vertex == v) return w;
else return v;
}
public int compareTo(Edge that)
{
if (this.get_weight() < that.get_weight()) return -1;
if (this.get_weight() < that.get_weight()) return 1;
else return 0;
}
public string to_str()
{
string s = v.ToString() + " " + weight.ToString() + " " + w.ToString() + '\n';
return s;
}
}
public class MyPriorityQueue_Edge
{
private List<Edge> q = new List<Edge>();
int size;
public MyPriorityQueue_Edge()
{
size = 0;
}
public void insert(Edge e)
{
q.Add(e);
size++;
}
Edge Min()
{
int min_weight = 1000;
Edge min_edge = new Edge();
foreach(Edge e in q)
if(e.get_weight()< min_weight)
min_edge = e;
return min_edge;
}
public Edge delmin()
{
Edge e = q.Min();
q.Remove(e);
size--;
return e;
}
public bool is_empty()
{
if (size == 0) return true;
else return false;
}
}
When I compile it the compiler points to this line:
Edge e = q.Min();
And says that I did not work on the exception "System.Argument.Exception". How can I fix this?
From MSDN Enumerable.Min<TSource> Method (IEnumerable<TSource>)
If type TSource implements IComparable<T>, this method uses that implementation to compare values. Otherwise, if type TSource implements IComparable, that implementation is used to compare values.
You need to implement IComparable interface in your Edge class.
public class Edge : IComparable
Then add a CompareTo() method. Something like
public int CompareTo(object obj)
{
if (obj is Edge)
{
Edge other = (Edge)obj;
return this.compareTo(other); // you already implemented this in your Edge class
}
else
{
throw new InvalidOperationException();
}
}
I've made a coroutine within C# using Unity 5 and I'd like to pass a reference to it. It didn't seem to work so I made a test script to try to isolate the following error.
error CS1623: Iterators cannot have ref or out parameters
Here's the test script:
using UnityEngine;
using System.Collections;
public class TEMP : MonoBehaviour {
// Use this for initialization
void Start () {
float var = 3.141f;
StartCoroutine ( test (ref var) );
}
IEnumerator test (ref float value) {
for (int i = 1; i <= 10; i++) {
Debug.Log (value);
yield return null;
}
}
}
In addition, on my actual script, I'm using Unity's WWW class to download something, and I also get this error when I pass www.progress as a reference:
A property or indexer 'UnityEngine.WWW.progress' may not be passed as 'ref' or 'out' parameter
Remove the ref from the function arguments.
// Use this for initialization
void Start () {
float var = 3.141f;
StartCoroutine ( test (var) );
}
IEnumerator test (float value) {
for (int i = 1; i <= 10; i++) {
Debug.Log (value);
yield return null;
}
}
Based on your requirement you could do something like below with an out parameter. I'm not exactly sure how you are intending to use these methods but I think you are getting the wrong idea about ref arguments and how they work.
class Program
{
static void Main(string[] args)
{
float var = 3.14f;
StartCoroutine(test(var), out var);
}
static IEnumerator test(float value)
{
for (int i = 1; i <= 10; i++)
{
Console.WriteLine(value);
yield return value + 1;
}
}
static void StartCoroutine(IEnumerator test, out float update)
{
update = 0;
while (test.MoveNext())
{
update++;
Console.WriteLine("Executing..." + update);
}
}
}
However you are never going to be able to pass a ref or out parameter to the interator.
Consider that
IEnumerator test (float value)
{
for (int i = 1; i <= 10; i++)
{
Debug.Log(value);
yield return null;
}
}
Is syntactic sugar for something like:
private class Iterator : IEnumerable<object>, IEnumerator<object>
{
private int _state;
private int _threadId = Environment.CurrentManagedThreadId;
private object _current;
private float _value;
int i;
public Iterator(float value)
{
_value = value;
}
public object Current‎
{
get { return _current; }
}
object IEnumerator.Current
{
get { return _current; }
}
public IEnumerator<object> GetEnumerator()
{
// If we're on the same thread and its the first call, reuse this object as the enumerator
// otherwise create a fresh one for new call (so we don't have buggy overlaps) or a different
// thread (to avoid a race on that first call).
Iterator iter = _state == 0 && _threadId == Environment.CurrentManagedThreadId ? this : new Iterator(_value);
iter._state = 1;
return iter;
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public bool MoveNext()
{
switch(_state)
{
case 1:
i = 1;
_state = 2;
goto case 2;
case 2:
if (i <= 10)
{
Debug.Log(_value);
_current = null;
++i;
return true;
}
_state = -1;
break;
}
return false;
}
public void Dispose()
{
}
public void Reset()
{
throw new NotSupportedException();
}
}
private IEnumerator test(float value)
{
return new Iterator(value);
}
Now, consider that your float parameter has become a float field in the implementation. Since you can't have a ref field, you can't have it as syntactic sugar for what looks like a ref parameter.
Hence your approach not only won't work (C# won't do it for you with yield taking away a lot of the coding) but can't work.
You'll need to box the float in some way, whether you are holding onto a object reference to the same float, that as a reference-type can be updated by the iterator, or a typed box like:
private class TypedBox<T> where T : struct
{
public T Value { get; set; }
public TypedBox(T value)
{
Value = value;
}
}
That again allows you to access the value via a reference-type, but without the casting cost.
More often its more useful just to have the value iterated based on any values passed in.
I am trying to make a dictionary key from 2 ints, I am thinking to combine them as follows
2 and 3 ---> 23
21 and 34 ---> 2134
etc etc
How would one acheive this, and if this is a bad approach, what would be better?
Thanks in advance
The following struct combines two integers and overrides equality members to make it usable as key in a dictionary. This solution is faster than my previous proposal using a Tuple<T1,T2> and less error prone than using a long.
public struct IntKey
{
private readonly int first;
private readonly int second;
public int First { get { return first; } }
public int Second { get { return second; } }
public IntKey(int first, int second)
{
this.first = first;
this.second = second;
}
public bool Equals(IntKey other)
{
return this.first == other.first && this.second == other.second;
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj))
{
return false;
}
return obj is IntKey && Equals((IntKey) obj);
}
public override int GetHashCode()
{
unchecked
{
return (this.first*397) ^ this.second;
}
}
}
[TestClass]
public class DictionaryTests
{
[TestMethod]
public void Test()
{
var dictionary = new Dictionary<IntKey, string>();
for (int j = 0; j < 3; j++)
{
dictionary.Clear();
var watch = Stopwatch.StartNew();
for (int i = 0; i < 1000000; i++)
{
dictionary.Add(new IntKey(i, i), "asdf");
}
Console.WriteLine(watch.ElapsedMilliseconds);
watch.Restart();
for (int i = 0; i < 1000000; i++)
{
var value = dictionary[new IntKey(i, i)];
}
Console.WriteLine(watch.ElapsedMilliseconds);
}
}
}
Try it. 1,000,000 writes or reads take about 250ms on my Azure VM.
If you know the max value for your int number, say 256 then you can do
firstInt * 256 + secondInt
the above will give you unique number with the performance benefit of the int.
Just reverse the calculation to get back the two numbers
I have an abstract class, Vector, which I would like to overload the operators +,-,*, etc.
I want any derived classes to be able to use these, and get an object back with the same type as the calling object.
I tried with generics, (as follows, in brief), but I couldn't find a legal way to do it:
public static T operator +<T>( T V1, T V2) where T : Vector
{
//some calculation
return new T(args);
}
I then tried to do it just using the base class:
public static Vector operator+(Vector V1, Vector V2)
{
if (V1.Dimension != V2.Dimension)
throw new VectorTypeException("Vector Dimensions Must Be Equal");
double[] ArgList = new double[V1.Dimension];
for (int i = 0; i < V1.Dimension; i++) { ArgList[i] = V1[i] + V2[i]; }
return (Vector)Activator.CreateInstance(V1.GetType(), new object[] { ArgList});
}
If this method is passed in two child objects, it should perform the operation on them, and return a new object of the same heritage.
The problem I ran into with this is that I cannot enforce that all such child classes must have a constructor with the appropriate signature, and I can't call the base constructor to make the object.
What are ways to either (a) Make either of these work, or (b) do this elegantly in another way?
You could declare instance-level abstract methods which your subclass can override:
public abstract class Vector
{
protected abstract Vector Add(Vector otherVector);
public static Vector operator +(Vector v1, Vector v2)
{
return v1.Add(v2);
}
}
public class SubVector : Vector
{
protected override Vector Add(Vector otherVector)
{
//do some SubVector addition
}
}
Might run into some issues especially with multiple subclasses (Will SubVector have to know how to add with SomeOtherSubVectorClass? What if you add ThirdVectorType class?) and perhaps handling null cases. Also, making sure that SubVector.Add behaves the same as SomeOtherSubVectorClass.Add when it comes to commutative operations.
EDIT: based on your other comments, you could so something like:
public class Vector2D : Vector
{
public double X { get; set; }
public double Y { get; set; }
protected override Vector Add(Vector otherVector)
{
Vector2D otherVector2D = otherVector as Vector2D;
if (otherVector2D != null)
return new Vector2D() { X = this.X + otherVector2D.X, Y = this.Y + otherVector2D.Y };
Vector3D otherVector3D = otherVector as Vector3D;
if (otherVector3D != null)
return new Vector3D() { X = this.X + otherVector3D.X, Y = this.Y + otherVector3D.Y, Z = otherVector3D.Z };
//handle other cases
}
}
public class Vector3D : Vector
{
public double X { get; set; }
public double Y { get; set; }
public double Z { get; set; }
protected override Vector Add(Vector otherVector)
{
Vector2D otherVector2D = otherVector as Vector2D;
if (otherVector2D != null)
return new Vector3D() { X = this.X + otherVector2D.X, Y = this.Y + otherVector2D.Y, Z = this.Z };
Vector3D otherVector3D = otherVector as Vector3D;
if (otherVector3D != null)
return new Vector3D() { X = this.X + otherVector3D.X, Y = this.Y + otherVector3D.Y, Z = this.Z + otherVector3D.Z };
//handle other cases
}
}
EDITx2:
Given your latest comment, perhaps your should just maintain an internal array/matrix and just do generic matrix math. Your subclasses can expose X/Y/Z property wrappers against the array indicies:
public class Vector
{
protected double[] Values;
public int Length { get { return Values.Length; } }
public static Vector operator +(Vector v1, Vector v2)
{
if (v1.Length != v2.Length)
{
throw new VectorTypeException("Vector Dimensions Must Be Equal");
}
else
{
//perform generic matrix addition/operation
double[] newValues = new double[v1.Length];
for (int i = 0; i < v1.Length; i++)
{
newValues[i] = v1.Values[i] + v2.Values[i];
}
//or use some factory/service to give you a Vector2D, Vector3D, or VectorND
return new Vector() { Values = newValues };
}
}
}
public class Vector2D : Vector
{
public double X
{
get { return Values[0]; }
set { Values[0] = value; }
}
public double Y
{
get { return Values[1]; }
set { Values[1] = value; }
}
}
public class Vector3D : Vector
{
public double X
{
get { return Values[0]; }
set { Values[0] = value; }
}
public double Y
{
get { return Values[1]; }
set { Values[1] = value; }
}
public double Z
{
get { return Values[2]; }
set { Values[2] = value; }
}
}
EDITx3: Based on your latest comment, I guess you could implement operator overloads on each subclass, do the shared logic in a static method (say in the base Vector class), and somewhere do a switch/case check to provide a specific subclass:
private static Vector Add(Vector v1, Vector v2)
{
if (v1.Length != v2.Length)
{
throw new VectorTypeException("Vector Dimensions Must Be Equal");
}
else
{
//perform generic matrix addition/operation
double[] newValues = new double[v1.Length];
for (int i = 0; i < v1.Length; i++)
{
newValues[i] = v1.Values[i] + v2.Values[i];
}
//or use some factory/service to give you a Vector2D, Vector3D, or VectorND
switch (newValues.Length)
{
case 1 :
return new Vector1D() { Values = newValues };
case 2 :
return new Vector2D() { Values = newValues };
case 3 :
return new Vector3D() { Values = newValues };
case 4 :
return new Vector4D() { Values = newValues };
//... and so on
default :
throw new DimensionOutOfRangeException("Do not support vectors greater than 10 dimensions");
//or you could just return the generic Vector which doesn't expose X,Y,Z values?
}
}
}
Then your subclasses would have:
public class Vector2D
{
public static Vector2D operator +(Vector2D v1, Vector2D v2)
{
return (Vector2D)Add(v1, v2);
}
}
public class Vector3D
{
public static Vector3D operator +(Vector3D v1, Vector3D v2)
{
return (Vector3D)Add(v1, v2);
}
}
Some duplication, but I don't see a way around it off the top of my head to allow the compiler to do this:
Vector3 v1 = new Vector3(2, 2, 2);
Vector3 v2 = new Vector3(1, 1, 1);
var v3 = v1 + v2; //Vector3(3, 3, 3);
Console.WriteLine(v3.X + ", " + v3.Y + ", " + v3.Z);
or for other dimensions:
Vector2 v1 = new Vector2(2, 2);
Vector2 v2 = new Vector2(1, 1);
var v3 = v1 + v2; //Vector2(3, 3, 3);
Console.WriteLine(v3.X + ", " + v3.Y); // no "Z" property to output!
What about having an abstract method called Add() that operator+ just acts as a wrapper for? ie, "return v1.Add(v2)". This would also enable you to define interfaces which non-Vector classes can constrain their code to, enabling to perform math-like operations (since generic code can't see/touch operators like +, -, etc for any type).
The only constructor you can code with in a generic method is the default (ie, parameter-less) constructor, which you have to specify in the generic constraints for the method/type.
Five years later I had the exact same problem, only I was calling them Ntuples, not vectors. Here is what I did:
using System;
using System.Collections.Generic;
public class Ntuple{
/*parent class
has an array of coordinates
coordinate-wise addition method
greater or less than in dictionary order
*/
public List<double> Coords = new List<double>();
public int Dimension;
public Ntuple(List<double> Input){
Coords=Input;
Dimension=Input.Count;
}//instance constructor
public Ntuple(){
}//empty constructor, because something with the + overload?
public static Ntuple operator +(Ntuple t1, Ntuple t2)
{
//if dimensions don't match, throw error
List<double> temp = new List<double>();
for (int i=0; i<t1.Dimension; i++){
temp.Add(t1.Coords[i]+t2.Coords[i]);
}
Ntuple sum = new Ntuple(temp);
return sum;
}//operator overload +
public static bool operator >(Ntuple one, Ntuple other){
//dictionary order
for (int i=0; i<one.Dimension; i++){
if (one.Coords[i]>other.Coords[i]) {return true;}
}
return false;
}
public static bool operator <(Ntuple one, Ntuple other){
//dictionary order
for (int i=0; i<one.Dimension; i++){
if (one.Coords[i]<other.Coords[i]) {return true;}
}
return false;
}
}//ntuple parent class
public class OrderedPair: Ntuple{
/*
has additional method PolarCoords, &c
*/
public OrderedPair(List<double> Coords) : base(Coords){}
//instance constructor
public OrderedPair(Ntuple toCopy){
this.Coords=toCopy.Coords;
this.Dimension=toCopy.Dimension;
}
}//orderedpair
public class TestProgram{
public static void Main(){
List<double> oneCoords=new List<double>(){1,2};
List<double> otherCoords= new List<double>(){2,3};
OrderedPair one = new OrderedPair(oneCoords);
OrderedPair another = new OrderedPair(otherCoords);
OrderedPair sum1 = new OrderedPair(one + another);
Console.WriteLine(one.Coords[0].ToString()+one.Coords[1].ToString());
Console.WriteLine(sum1.Coords[0].ToString()+sum1.Coords[1].ToString());
bool test = one > another;
Console.WriteLine(test);
bool test2 = one < another;
Console.WriteLine(test2);
}
}
}//namespace ntuples